The streaming engine that starts embedded
Sub-microsecond SQL over event streams. Embed in Rust or Python, run as a standalone server, or scale to a cluster. No JVM.
let db = LaminarDB::open()?;
db.execute("CREATE SOURCE trades (
symbol VARCHAR, price DOUBLE, volume BIGINT, ts BIGINT
)").await?;
db.execute("CREATE STREAM vwap AS
SELECT symbol,
SUM(price * CAST(volume AS DOUBLE))
/ SUM(CAST(volume AS DOUBLE)) AS vwap
FROM trades
GROUP BY symbol, tumble(ts, INTERVAL '1' MINUTE)
EMIT ON WINDOW CLOSE
").await?;
db.start().await?;
What it is
LaminarDB is a streaming SQL engine. Write SQL queries over event streams — windows, joins, aggregations — and the engine evaluates them continuously as events arrive. Built on Apache Arrow 57 and DataFusion 52.
Three deployment modes.
Embed it in your application — Rust (cargo add laminar-db) or Python (pip install laminardb).
Run it as a standalone server (laminardb binary) with Kafka, CDC, and Delta Lake connectors.
Or deploy as a cluster — distributed mode is coming soon.
It is not a message broker (it consumes from Kafka, doesn't replace it) and it is not a general-purpose OLTP/OLAP database — it processes streams.
Quick start
Add the dependency and write your first streaming query.
// Cargo.toml: laminar-db = "0.18", tokio = { version = "1", features = ["full"] }
use laminar_db::LaminarDB;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let db = LaminarDB::open()?;
db.execute("CREATE SOURCE events (
key VARCHAR, value DOUBLE, ts BIGINT
)").await?;
db.execute("CREATE STREAM summary AS
SELECT key, COUNT(*) AS total, AVG(value) AS avg
FROM events
GROUP BY key, tumble(ts, INTERVAL '1' MINUTE)
EMIT ON WINDOW CLOSE
").await?;
db.start().await?;
// Push events into the source (typed via derive macro)
let source = db.source::<Event>("events")?;
source.push(Event { key: "sensor-1".into(), value: 42.0, ts: 1700000000000 });
// Subscribe to streaming results
let sub = db.subscribe::<Summary>("summary")?;
while let Some(rows) = sub.poll() {
for row in &rows {
println!("{}: count={}, avg={:.2}", row.key, row.total, row.avg);
}
}
Ok(())
}
-- Tumbling window: 1-minute OHLC bars
CREATE STREAM ohlc_1m AS
SELECT symbol,
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(ts, INTERVAL '1' MINUTE)
EMIT ON WINDOW CLOSE;
-- Session window: detect activity bursts
CREATE STREAM sessions AS
SELECT user_id, COUNT(*) AS clicks,
MAX(ts) - MIN(ts) AS duration_ms
FROM clickstream
GROUP BY user_id, session(ts, INTERVAL '30' SECOND)
EMIT ON WINDOW CLOSE;
-- ASOF join: enrich trades with closest preceding quote
SELECT t.symbol, t.price, q.bid, q.ask,
t.price - q.bid AS spread
FROM trades t
ASOF JOIN quotes q
MATCH_CONDITION(t.ts >= q.ts)
ON t.symbol = q.symbol;
-- Interval join: match orders to payments within 1 hour
CREATE STREAM matched AS
SELECT o.order_id, o.amount, p.status
FROM orders o
INNER JOIN payments p ON o.order_id = p.order_id
AND p.ts BETWEEN o.ts AND o.ts + 3600000;
-- Temporal join: point-in-time lookup
SELECT o.*, r.rate
FROM orders o
JOIN rates FOR SYSTEM_TIME AS OF o.order_time AS r
ON o.currency = r.currency;
# Option 1: Download pre-compiled binary (latest release)
VERSION=$(curl -s https://api.github.com/repos/laminardb/laminardb/releases/latest | grep tag_name | cut -d '"' -f4)
# Linux x86_64
curl -LO "https://github.com/laminardb/laminardb/releases/download/${VERSION}/laminardb-server-x86_64-unknown-linux-gnu-${VERSION}.tar.gz"
tar xzf laminardb-server-*.tar.gz
# macOS Apple Silicon
curl -LO "https://github.com/laminardb/laminardb/releases/download/${VERSION}/laminardb-server-aarch64-apple-darwin-${VERSION}.tar.gz"
# All platforms: github.com/laminardb/laminardb/releases
# Option 2: Build from source
cargo install laminar-server
# Option 3: Docker
docker compose up
# Run
./laminardb --config laminardb.toml
-- Kafka source with Avro and Schema Registry
CREATE SOURCE trades (
symbol VARCHAR, price DOUBLE, volume BIGINT, ts BIGINT
) FROM KAFKA (
brokers = 'localhost:9092',
topic = 'market-trades',
group_id = 'laminar-analytics',
format = 'avro',
schema.registry.url = 'http://schema-registry:8081'
);
-- Real-time aggregation
CREATE STREAM trade_summary AS
SELECT symbol, COUNT(*) AS trades,
AVG(price) AS avg_price,
SUM(volume) AS total_volume
FROM trades
GROUP BY symbol, tumble(ts, INTERVAL '1' MINUTE)
EMIT ON WINDOW CLOSE;
-- Kafka sink with exactly-once delivery
CREATE SINK output INTO KAFKA (
brokers = 'localhost:9092',
topic = 'trade-summaries',
format = 'json',
delivery.guarantee = 'exactly-once'
) AS SELECT * FROM trade_summary;
-- Delta Lake sink for historical analytics
CREATE SINK lake INTO DELTA_LAKE (
path = 's3://my-bucket/trade_summary',
write_mode = 'append',
delivery.guarantee = 'exactly-once'
) AS SELECT * FROM trade_summary;
More examples: examples/ · API reference · SQL reference
Connectors
All connectors are feature-gated. Compile only what you use.
Enable via cargo add laminar-db --features kafka,delta-lake.
| Connector | Direction | Status | Feature Flag | Notes |
|---|---|---|---|---|
| Kafka | Source + Sink | Implemented | kafka |
Avro, JSON, CSV. Confluent Schema Registry. Exactly-once via 2PC. |
| PostgreSQL CDC | Source | Implemented | postgres-cdc |
Logical replication via pgoutput. LSN-based checkpoint tracking. |
| PostgreSQL Sink | Sink | Implemented | postgres-sink |
COPY BINARY (append) or INSERT ON CONFLICT (upsert). |
| MySQL CDC | Source | Implemented | mysql-cdc |
Binlog replication. GTID or file+position modes. |
| MongoDB CDC | Source + Sink | Implemented | mongodb-cdc |
Change streams, resume tokens. Sink: ordered/unordered writes, upsert, CDC replay. |
| Delta Lake | Source + Sink | Implemented | delta-lake |
S3, Azure, GCS, Unity, Glue catalogs. Exactly-once epoch tracking. |
| WebSocket | Source + Sink | Implemented | websocket |
Client and server modes. JSON/CSV serialization. |
| File Auto-Loader | Source + Sink | Implemented | files |
CSV, JSON Lines, Parquet, plain text. Schema inference and evolution. |
| Parquet Lookup | Source | Implemented | parquet-lookup |
Object-store-backed dimension tables for lookup joins. |
Custom connectors: implement the SourceConnector / SinkConnector traits.
Deployment
Embedded
Rust: cargo add laminar-db.
Python: pip install laminardb.
The engine runs in your process — push events, subscribe to results.
Good fit for edge processing, embedded analytics, and latency-sensitive apps.
Standalone Server
Download pre-compiled binaries
for Linux (x86_64, aarch64, musl), macOS (x86_64, Apple Silicon), and Windows.
Or cargo install laminar-server. Docker image and Helm chart available.
TOML configuration with ${ENV_VAR} substitution.
REST API, Prometheus metrics, ad-hoc SQL, and hot-reload (edit config → automatic apply).
Use for: CDC pipelines, stream-to-lakehouse, event routing.
Cluster
Coming SoonMulti-node deployment using Raft consensus and gossip discovery. Core primitives are in the workspace — cluster mode is being wired into the server.
How it compares
Different tools for different problems. LaminarDB targets low-latency, single-node workloads today — cluster mode is coming.
| LaminarDB | Apache Flink | Kafka Streams | Arroyo | kdb+ | |
|---|---|---|---|---|---|
| Type | SQL engine | Distributed framework | Stream library (JVM) | Distributed engine | Timeseries DB |
| Language | Rust + Python | Java / Scala | Java | Rust | q/k (proprietary) |
| SQL | DataFusion | Flink SQL | None | DataFusion | q language |
| Deployment | Embedded, server, cluster (soon) | Cluster (YARN/K8s) | In-app (JVM) | Kubernetes | Single process |
| Latency target | 10–16ns state lookup | ~10ms | ~1ms | ~10ms | <1µs |
| Horizontal scale | No (single node) | Yes | Via Kafka partitions | Yes | No |
| Exactly-once | Barrier checkpoints | Barrier checkpoints | Kafka transactions | Barrier checkpoints | N/A |
| Connectors | 10 | 100+ | Kafka only | 15+ | Custom |
| Ops overhead | None (lib) / low | High (cluster, JVM) | Low | Medium (K8s) | Low |
| License | Apache 2.0 | Apache 2.0 | Apache 2.0 | Apache 2.0 | Proprietary |
| Maturity | Pre-1.0 (v0.18.12) | Production (10+ yrs) | Production (8+ yrs) | Production (~2 yrs) | Production (30+ yrs) |
Bold cells show where a competitor has a clear advantage. LaminarDB wins on latency and deployment flexibility. It loses on maturity, horizontal scale, and ecosystem breadth.
When to choose something else
Apache Flink
Need to scale across a cluster? Flink handles 100+ connectors and complex event processing. Trade-off: heavyweight JVM footprint and operational overhead.
Kafka Streams
Strictly Kafka in/out and already running JVM services? Streams is the simplest fit. No SQL though.
Arroyo
Distributed streaming in Rust with a web UI. Runs on Kubernetes. Shares the DataFusion SQL foundation with LaminarDB.
kdb+
Finance teams with q/k expertise and sub-microsecond timeseries analytics. 30+ years of production track record. Licensing is steep.
Benchmarks
Criterion benchmarks run on an AMD Ryzen AI 7 350 laptop. These are not server numbers. Dedicated hardware with isolated cores will perform better. Full results.
| Metric | Target | Measured | Benchmark File |
|---|---|---|---|
| State lookup (AHash get_ref) | <500ns | 10–16ns (zero-copy) | state_bench.rs |
| Throughput / core | 500K events/s | 1.1–1.46M events/s | streaming_bench.rs |
| Event latency (mean) | <10µs | 0.55–1.16µs | latency_bench.rs |
| Checkpoint recovery | <10s | 1.39ms | checkpoint_bench.rs |
| WAL append | <1µs | 541ns | wal_bench.rs |
Reproduce: cargo bench --bench state_bench,
cargo bench --bench streaming_bench,
cargo bench --bench latency_bench.
All benchmarks use Criterion for statistical analysis.
Status
Current version: 0.18.12 (pre-1.0). Releases · Roadmap
Stable
- Core engine (reactor, state stores, DAG executor)
- Window functions (tumbling, sliding, hopping, session)
- Joins (interval, ASOF, temporal, lookup, semi/anti)
- All 10 connectors (Kafka, CDC, MongoDB, Delta, WS, files)
- Barrier-based checkpointing with 2PC exactly-once
- Per-core WAL for durability
- Standalone server with REST API, Prometheus metrics, hot-reload
- Docker (multi-arch) and Helm chart deployment
Experimental
- io_uring storage (Linux only, feature-gated)
- Incremental checkpoints
Not yet implemented
- Cluster / multi-node deployment (coming soon)
- PostgreSQL wire protocol (planned)
- Redis connector
Contributing
LaminarDB is Apache 2.0 licensed. Contributions welcome. Rust 1.85+ required. See the contribution guide for Ring 0 constraints (no allocations, no locks, no syscalls on the hot path).