Single-file embedded DB forkbve
Turso (async write) paired with DuckDB (analytics read) over one SQLite-format file — parallel reader pool, streaming reads, batched writes, and a FromEmbedRow derive.
One file, two engines
Turso writes and DuckDB analytics over a single SQLite-format file. The derive macro ships in embeddb-derive.
- Write — Turso async, parameterized, transactions.
- Read — DuckDB pool, streaming, columnar analytics.
What it gives you
Features
Turso write path
Pure-Rust async SQLite rewrite for parameterized writes, transactions, and batched inserts.
DuckDB analytics pool
A pooled read-only DuckDB reader for parallel columnar analytics over the same file, built lazily on first use.
Streaming + batch
analytics_for_each streams rows without materializing; execute_batch runs many writes in one transaction.
Row mapping
EmbedValue type set, QueryResult with column names, and
Live-read freshness
DuckDB replays uncheckpointed WAL, so analytics reflect committed writes without a forced checkpoint.
Questions
Frequently asked
What is the embeddb crate?
embeddb is a foundational Rust library providing a single-file embedded database. It pairs Turso (a pure-Rust async SQLite rewrite) as the write path with DuckDB as the analytics read path over one SQLite-format file, so a single file gives both transactional writes and columnar analytics.
What does embeddb provide?
Parameterized writes and transactions via Turso, a DuckDB reader pool for parallel analytics, streaming row callbacks, batched writes, migrations and config, a rich EmbedValue type set, QueryResult with column names, and a FromEmbedRow derive for mapping rows into structs.
How does concurrency and freshness work?
Turso owns all writes; DuckDB attaches the same file read-only for analytics. DuckDB replays uncheckpointed WAL frames, so analytics reflect committed writes even before a checkpoint, and concurrent reads stay consistent. The reader pool builds lazily on the first analytics call, so write-only use never loads the analytics engine.
