The Embedded
Streaming Database

Sub-microsecond SQL stream processing. No cluster required.

0 ns < 1µs end-to-end
MIT Rust 2000+ Tests 65 Features

Why LaminarDB

Think DuckDB, but for streaming. Embed a full streaming database directly in your application.

Sub-Microsecond Latency

Zero allocations on the hot path. No GC pauses, no JVM warmup. 325ns measured through a 3-node pipeline.

< 1µs hot path • 325ns measured

Embedded-First

Single binary, no cluster, no external dependencies. Embed in your application like DuckDB.

cargo add laminar-db

SQL-Native Streaming

Full SQL via DataFusion with streaming extensions: TUMBLE, HOP, SESSION, EMIT, ASOF JOIN, and 30+ aggregates.

DataFusion + streaming SQL

Exactly-Once Guaranteed

Write-ahead log, incremental checkpointing, two-phase commit, and co-transactional sinks.

WAL + 2PC + epoch tracking

Why DuckDB for Streaming?

DuckDB changed analytics by proving you don't need a cluster to run fast SQL queries — just embed it in your process. No deployment, no network hops, no operational overhead.

Streaming has the same problem today. Running real-time aggregations or CDC pipelines typically means deploying and maintaining a distributed system like Apache Flink or RisingWave — even when your workload fits on a single machine.

LaminarDB takes the DuckDB approach for stream processing:

  • Add a dependency, not a cluster. cargo add laminar-db gives you windowed aggregations, stream joins, watermarks, and exactly-once semantics inside your application.
  • No serialization boundary. Data stays in Apache Arrow columnar format in your process. No network encoding/decoding overhead.
  • Same SQL you know. Full DataFusion SQL engine with streaming extensions (TUMBLE, HOP, SESSION, EMIT, ASOF JOIN).
  • Production semantics. Write-ahead log, incremental checkpointing, and two-phase commit — the same guarantees distributed systems provide, without the distributed part.

If your streaming workload fits on one machine, you don't need a cluster. Most workloads do.

Thread-Per-Core Architecture

Most streaming systems use thread pools with shared state, which means locks, contention, and unpredictable latency spikes from context switching. LaminarDB uses a thread-per-core model instead — the same architecture behind ScyllaDB, Redpanda, and Seastar.

How it works

  • One reactor per CPU core. Each core runs its own event loop, pinned with CPU affinity. No thread migration, no cache thrashing.
  • Shared-nothing state. Each core owns its partition of the keyspace. No locks anywhere on the hot path.
  • SPSC queues between cores. Lock-free single-producer single-consumer queues (~4.8ns per operation) for cross-core communication.
  • Zero allocations on hot path. Arena allocators and pre-allocated buffers. A debug-mode allocation detector verifies this in CI.

Why it matters

  • Predictable latency. No GC pauses (Rust), no lock contention, no thread pool scheduling jitter. The p99 stays close to the median.
  • Linear scaling. Adding cores adds proportional throughput. 4 cores = ~4x throughput, not diminishing returns from lock contention.
  • Cache efficiency. Pinned cores keep working data in L1/L2 cache. No cross-core cache invalidation on the hot path.

Measured Performance

Criterion benchmarks on a 3-node DAG pipeline. All numbers from cargo bench.

Routing lookup
4ns
3-node latency
325ns
State lookup p99
< 500ns
Target budget
1µs
2.24M
events/sec per core (linear pipeline)
660K
events/sec (10-operator deep pipeline)
< 10s
checkpoint recovery target

See It In Action

Streaming SQL, real-time joins, embedded Rust API, and CDC pipelines.

-- Real-time OHLC bars from a trade stream
CREATE MATERIALIZED VIEW ohlc_1m AS
SELECT
  symbol,
  TUMBLE_START(event_time, INTERVAL '1' MINUTE) AS bar_start,
  FIRST_VALUE(price) AS open,
  MAX(price) AS high,
  MIN(price) AS low,
  LAST_VALUE(price) AS close,
  SUM(volume) AS volume
FROM trades
GROUP BY
  symbol,
  TUMBLE(event_time, INTERVAL '1' MINUTE)
EMIT ON WINDOW CLOSE;
-- ASOF JOIN: enrich trades with latest quote
SELECT
  t.symbol,
  t.price AS trade_price,
  t.quantity,
  q.bid,
  q.ask,
  t.price - q.bid AS spread
FROM trades t
ASOF JOIN quotes q
  ON t.symbol = q.symbol
  AND t.event_time >= q.event_time
  TOLERANCE INTERVAL '5' SECOND;
use laminar_db::LaminarDB;

#[tokio::main]
async fn main() -> Result<(), Box> {
    let db = LaminarDB::open("./my_stream_db").await?;

    // Create a streaming query
    db.execute("
        CREATE MATERIALIZED VIEW alerts AS
        SELECT sensor_id, AVG(temperature) AS avg_temp
        FROM sensors
        GROUP BY sensor_id, TUMBLE(event_time, INTERVAL '10' SECOND)
        HAVING AVG(temperature) > 100.0
        EMIT ON WINDOW CLOSE
    ").await?;

    // Ingest events
    let source = db.source("sensors").await?;
    source.push(sensor_event).await?;

    // Query results
    let results = db.query("SELECT * FROM alerts").await?;
    println!("{:?}", results);

    Ok(())
}
-- Stream changes from PostgreSQL to Kafka
CREATE SOURCE orders_cdc
WITH (
  connector = 'postgres-cdc',
  hostname = 'db.example.com',
  port = '5432',
  database = 'shop',
  table = 'orders',
  slot.name = 'laminar_orders'
);

CREATE SINK order_totals_kafka
WITH (
  connector = 'kafka',
  brokers = 'kafka:9092',
  topic = 'order-totals',
  format = 'json'
) AS
SELECT
  customer_id,
  COUNT(*) AS total_orders,
  SUM(amount) AS total_spent
FROM orders_cdc
WHERE _op IN ('I', 'U')
GROUP BY customer_id
EMIT CHANGES;

Three-Ring Architecture

Strict isolation between hot path, background I/O, and control plane.

Ring 0: Hot Path < 1µs • zero allocations • no locks
Reactor
Operators
State Store
Emit
SPSC Queues (lock-free)
Ring 1: Background async I/O • bounded latency impact
Checkpoint
WAL
Compaction
io_uring
Bounded Channels
Ring 2: Control Plane no latency requirements • full flexibility
Admin API
Metrics
Auth
Config

Built For Real Workloads

From financial analytics to IoT edge processing.

Financial Analytics

  • OHLC bars with FIRST/LAST aggregates
  • ASOF joins for trade-quote enrichment
  • Cascading MVs for multi-resolution (1s, 1m, 1h)
  • Keyed watermarks for 99%+ accuracy

IoT & Edge Processing

  • Embedded deployment, single binary
  • Local aggregation before cloud
  • Sub-millisecond response times
  • Thread-per-core for sensor data

Real-Time Applications

  • Gaming leaderboards and scoring
  • Fraud detection pipelines
  • Dynamic pricing engines
  • Event-driven architectures

Data Infrastructure

  • CDC from PostgreSQL and MySQL
  • Stream-to-lake (Delta Lake, Iceberg)
  • Lightweight alternative for single-node workloads
  • Kafka source and sink connectors

65 Features And Counting

Production-grade streaming across engine, SQL, durability, and connectors.

Reactor Event Loop Single-threaded, CPU-pinned event processing Done
Memory-Mapped State FxHashMap with cache-aligned lookups < 500ns Done
Tumbling Windows Fixed-size non-overlapping time windows Done
Sliding & Session Windows Overlapping and gap-based windows Done
Event Time & Watermarks Per-partition, per-key, alignment groups Done
EMIT Clause ON WINDOW CLOSE, CHANGES, FINAL modes Done
Changelog / Retraction Z-set foundation for correct incremental updates Done
Cascading MVs Materialized views reading from other MVs Done
Late Data Handling Configurable allowed lateness with side output Done
DAG Pipeline Multi-node topology with fan-out, multicast, routing Done
Composite Aggregator 30+ aggregates, FILTER, WITHIN GROUP support Done
FIRST/LAST Value Retractable accumulators for OHLC patterns Done
DataFusion Integration Full Apache DataFusion query engine Done
Streaming SQL Parser CREATE SOURCE/SINK, window functions, EMIT Done
Window UDFs TUMBLE, HOP, SESSION as scalar UDFs Done
Watermark UDF Real-time watermark() function via AtomicI64 Done
Aggregate Bridge DataFusion Accumulator ↔ streaming DynAccumulator Done
Query Planner Streaming-aware plan generation Done
Join Analysis Auto-detect stream-stream, lookup, temporal joins Done
SQL DDL CREATE SOURCE/SINK → connector configs Done
Stream-Stream Joins Inner, Left, Right, Full outer with time bounds Done
Lookup Joins Cached with TTL for dimension enrichment Done
Temporal Joins Event-time and process-time versioned joins Done
ASOF Joins Backward, Forward, Nearest with tolerance Done
Join Optimizations CPU-friendly encoding, asymmetric compaction Done
Write-Ahead Log CRC32C, fdatasync, torn write detection Done
Per-Core WAL Lock-free per-core writers with epoch ordering Done
Incremental Checkpointing RocksDB backend, SPSC changelog, async I/O Done
Exactly-Once Sinks Transactional + idempotent sink adapters Done
Two-Phase Commit Presumed abort with crash recovery Done
DAG Checkpointing Chandy-Lamport barrier-based through DAG edges Done
Thread-Per-Core SPSC queues, key routing, CPU pinning Done
SPSC Queues Lock-free ~4.8ns per operation Done
io_uring Advanced SQPOLL, registered buffers, IOPOLL for NVMe Done
NUMA-Aware Memory Per-core NUMA-local allocation Done
Three-Ring I/O Latency, main, poll ring separation Done
Task Budget Ring 0: 500ns, Ring 1: 1ms budget enforcement Done
Zero-Allocation Hot Path Debug-mode detector + CI enforcement Done
Zero-Alloc Polling Pre-allocated buffers, callback-based APIs Done
XDP/eBPF Wire-speed packet filtering, CPU steering Done
Kafka Source Consumer groups, backpressure, Schema Registry Done
Kafka Sink Transactional, idempotent, partitioning strategies Done
PostgreSQL CDC Full pgoutput protocol, Z-set changelog Done
PostgreSQL Sink COPY BINARY, upsert, co-transactional exactly-once Done
Connector Bridge DAG ↔ external connectors with runtime orchestration Done
Delta Lake Sink Stream to Delta Lake tables Coming Soon
Iceberg Sink Stream to Apache Iceberg tables Coming Soon
MySQL CDC Source Binlog-based change data capture Coming Soon
Connector SDK Build custom source/sink connectors Coming Soon
RBAC / ABAC Role and attribute-based access control Coming Soon
Admin Dashboard Web UI for pipeline management Coming Soon
Prometheus Export Metrics export for monitoring Coming Soon
OpenTelemetry Distributed tracing support Coming Soon

How We Compare

Different tools for different needs. LaminarDB is embedded-first and optimized for single-node, low-latency workloads.

Feature LaminarDB Flink Kafka Streams RisingWave Materialize
Deployment Embedded Distributed Embedded Distributed Distributed
Latency (in-process) < 1µs N/A* ~1ms N/A* N/A*
SQL Support Full Limited None Full Full
Exactly-Once
Thread-per-Core
Language Rust Java Java Rust Rust / C++
Lakehouse Planned Limited
Embedded Mode
License MIT Apache 2.0 Apache 2.0 Apache 2.0 BSL

* Flink, RisingWave, and Materialize are distributed systems — their latency includes network hops and is not directly comparable to in-process embedded latency. Kafka Streams is the closest comparison as it is also embedded.

Get Started

Up and running in three steps.

1

Add the dependency

cargo add laminar-db
2

Create and query

use laminar_db::LaminarDB;

#[tokio::main]
async fn main() -> Result<(), Box> {
    let db = LaminarDB::open("./my_db").await?;

    db.execute("
        CREATE MATERIALIZED VIEW summary AS
        SELECT key, COUNT(*) AS total
        FROM events
        GROUP BY key, TUMBLE(event_time, INTERVAL '1' MINUTE)
        EMIT ON WINDOW CLOSE
    ").await?;

    let results = db.query("SELECT * FROM summary").await?;
    println!("{:?}", results);
    Ok(())
}
3

Run it

cargo run

Open Source.
MIT.

LaminarDB is open source and free to use. Contributions welcome.

Rust
Apache Arrow
DataFusion