Pre-1.0 — active development
Twill DB is under active development (currently 0.x). Interfaces, the SQL surface, on-disk and storage formats, and behaviour may change between releases — backward compatibility is not guaranteed until the 1.0.0 release. Pin an exact version and review the release notes before upgrading.
Where the project stands
Every capability is implemented and gated by tests; the storage seam has never moved, so each one was purely additive. The project grows further by composition.
Shipped
Embedded library ✓ Shipped
libengine + engine.h + @twilldb/bun + LocalFileStorage
The engine as an in-process library bound into Bun via bun:ffi, backed by LocalFileStorage (a plain file:// database, no network). SQL → MVCC snapshot isolation → crash-safe WAL durability with deterministic replay. The C ABI is frozen here and reused unchanged by everything built since.
Gate: basic SQL correctness + MVCC snapshot isolation; durable-after-ack with torn-frame recovery. Implementation map → · Engine Core spec
Object-storage backend ✓ Shipped
ObjectStorage (LSM page store + S3-CAS commit log)
A second Storage impl makes the database disaggregated and scale-to-zero — while staying embedded. Flip the connection string from file:// to s3:///r2:///gs:// and the same binary durably bottoms out on object storage, with the local cache keeping S3 latency off the read hot path.
Gate: commit-latency floor, group-commit throughput, and crash-safety (every acked commit survives kill -9). Implementation map → · Object-Storage spec
Server mode + pgwire ✓ Shipped
engine-server (Postgres-wire subset)
The same engine wrapped in a Postgres-wire listener. Ordinary Postgres clients — psql, Bun.sql, pgbench, PostgREST — connect with no bespoke driver. The server links the engine's Rust API unchanged and adds exactly one thing: the listener.
Gate: serves Bun.sql and pgbench over the wire; contention behaviour reproduces in server mode. Implementation map → · Server Mode spec
Branching & lifecycle ✓ Shipped
BranchStorage + durable single-writer lease + twill-controller
Copy-on-write branching as a storage-seam concern (a parent read-through below the fork LSN plus a private write overlay), a durable single-writer lease fenced by a monotonic CAS epoch, and a scale-to-zero lifecycle controller (cold-start, idle reaper, lease heartbeat, thundering-herd admission). All additive: STORAGE_TRAIT_VERSION and ENGINE_ABI_VERSION bumped to 2.
Gate: scale-to-zero + cold-start with the fence re-acquired by exactly one writer; O(1) branch creation with write isolation. Implementation map → · Lifecycle spec
Vector search (in-core) ✓ Shipped
in-core vector(N) type + HNSW + distance operators + KNN · composition
Vector search built into the engine: a vector(N) type, an HNSW access method (CREATE INDEX … USING hnsw), the distance operators <-> / <=> / <#>, and top-k nearest-neighbour answered by the index. Because the index rides the same WAL/replay path as the rows, it branches and scales-to-zero with the database — an agent can fork its memory. Interface/service capabilities (better-auth, PostgREST, DuckDB) are composed around the core, never welded in. Additive: ENGINE_ABI_VERSION → 3, STORAGE_TRAIT_VERSION stays 2.
Gate: HNSW top-k matches brute force; WHERE-filtered + MVCC-correct KNN; the index branches and rebuilds from the WAL on restart. Implementation map → · Capabilities spec
SQL surface completeness ✓ Shipped
richer SQL frontend (6A–6E) — parser + executor only; the storage seam never moved
The hand-written SQL frontend (sql.rs → exec.rs) grown to cover the common, OLTP-shaped majority of the PostgreSQL and SQLite surface, in five additive stages: 6A expression & single-table (CASE, CAST/::, IN/BETWEEN, ||, RETURNING, upsert, INSERT … SELECT); 6B multi-table (joins, GROUP BY/HAVING, subqueries, set ops, views & CTEs); 6C the scalar function library (string / math / date-time / uuid / JSON); 6D constraints, schema evolution & savepoints (CHECK/DEFAULT/UNIQUE, ALTER TABLE, SAVEPOINT); 6E dialect shims (placeholders, quoting, LIKE/ILIKE, SET/SHOW/PRAGMA). Pure frontend growth — STORAGE_TRAIT_VERSION and ENGINE_ABI_VERSION never moved; anything still unsupported returns a clean ENGINE_ERR_SQL.
Gate: per-stage test binaries (expr_6a, relational_6b, functions_6c, constraints_6d, dialect_6e) all green; the C1–C8 conformance suite, branching, and scale-to-zero untouched. Implementation map → · SQL Compatibility spec
Row-Level Security ✓ Shipped
in-core per-row enforcement (Phase 7) · JWT identity composed around
Supabase-style RLS built into the engine and enforced over the same MVCC snapshot every query already uses. CREATE/DROP POLICY and ALTER TABLE … ENABLE ROW LEVEL SECURITY persist as additive WAL catalog facts; a per-connection session context (role + JWT claims via SET ROLE / SET twill.jwt.claims) is read by auth.uid() / auth.role() / auth.claim(). Enforcement is default-deny — USING on reads, WITH CHECK on writes, RLS-filtered RETURNING, and an explicit off-by-default bypass — reflected through pg_policies. JWT verification stays composed around the engine, so PostgREST-style identity layers on without entering the core. Additive: ENGINE_ABI_VERSION and STORAGE_TRAIT_VERSION both unchanged, so policies branch / scale-to-zero / PITR-restore for free.
Gate: default-deny read/write enforcement on the single-table and relational paths; bypass off unless explicitly set; policies survive branch + replay. Row-Level Security spec
CLI tooling & multi-runtime clients ✓ Shipped
twilldb scaffolder + management CLI (spec 19) · @twilldb/node + PHP clients (spec 20)
A dependency-free twilldb scaffolder (new/init, with a --vector HNSW template) and a full database-management CLI — sql, shell, tables, migrate, gen types, seed, stats, branch, db reset, schema dump, serve — over both embedded (file:///s3://) and over-the-wire (postgres://) transports. Alongside them, @twilldb/node (koffi FFI) and twilldb/twilldb (PHP FFI) join the Bun client with the same surface.
Gate: management tests behind the manage feature green while the default scaffolder build stays lean; Node + PHP embedded e2e suites pass. CLI Tooling · Management CLI · Client Runtimes
Roadmap
Twill Bench CLI ✓ Scenarios shipped
benchmarking + correctness + serverless-efficiency CLI
The crates/bench driver — today's spec-09 latency floor, group-commit curve and contention wall over both transports (embedded FFI + pgwire) and both backends (file:// / s3://) — grown into the full Twill Bench tool: one driver that answers is it fast, is the data still correct under stress, and how efficiently did the serverless architecture use compute. All committed scenarios have shipped. Per the architecture guardrails, reporting/export stays CLI-only and feature-gated, and lifecycle metrics are sourced from twill-controller and the server, never the thread-free engine core.
- Mix ✓Request-mix scenarios —
read-heavy/write-heavy/mixed-oltpwith ratio control over a seeded working set, deterministic per-writer PRNG. Shipped. - Check ✓Correctness profiles —
counter,bank-transfer,inventory, anddocument-editingwith ACID-invariant assertions (a violation fails with exit code 2). Shipped. - Report ✓Reporting —
--json-only mode, the full 0–4 exit-code table, p90/p95 percentiles, andcompare --baseline --candidatefor release-over-release diffs. Shipped. - Lifecycle ✓Lifecycle scenarios & serverless-efficiency metrics —
scale-to-zero(Exp 5 cold read),burst(closed-loop rate driver),long-run(interval sampler + leak/drift detection), and a feature-gatedcustom --profile workload.yamlloader; compute active/idle, scale-to-zero count, compute-seconds/query. Shipped (issues #78–#81).
Detail in Twill Bench CLI; tracked in issue #49. Remaining work is the ongoing spec-09 five-experiment validation (epic #91), not the CLI surface.
Vector hardening ✓ Shipped
deferred items from the vector-search scope boundaries — landed in v0.5.0
- DonePage-laid-out vector index improvements for cold reads, on top of the WAL-derived index that branches and rebuilds on open.
- DoneDelete-churn maintenance so tombstoned deletes no longer degrade the graph over time.
- DoneRecall tuning via
ef_search— the HNSW recall/latency trade-off is now surfaced and documented.
Detail in Capabilities: Build-in vs Compose and the vector-search implementation map; delivered under epic #89.
Exploratory / parallel tracks Exploring
- MAY add a WASM build track (Cloudflare Workers + R2) as a parallel deliverable — a port, not a recompile, and off the native critical path. See Deployment Targets.
- MAY decide NAPI vs FFI for a single Bun + Node package if that becomes a hard requirement.
- SHOULD make the exact pgwire subset boundary explicit — the minimum for
Bun.sql/ PostgREST /pgbenchmay be smaller than full Postgres compatibility. - MUST keep the per-tool go/no-go decision attached to rollout, routing write-heavy hot-row outliers to coupled Postgres rather than blocking a gate. See Hot-Row Contention.
Scoped in epic #90.
Milestone table
Each milestone is independently shippable and adds exactly one capability, because the seam below it never moves.
| Milestone | Headline deliverable | Gate(s) | State after |
|---|---|---|---|
| M1 — Embedded ✓ | libengine + engine.h + @twilldb/bun + LocalFileStorage | Basic correctness + MVCC snapshot | In-process persistent DB, zero infra |
| M2 — Disaggregated ✓ | ObjectStorage (LSM page store + S3-CAS log) | Commit latency, group commit, durability | Disaggregated + scale-to-zero, still embedded |
| M3 — Server ✓ | engine-server + pgwire subset + pooler guidance | Group-commit + contention in server mode | Multi-client; PostgREST + Bun.sql for free |
| M4 — Controller ✓ | Lifecycle state machine + branch-on-LSN + CAS fencing | Cold read + thundering-herd | True scale-to-zero + instant clones |
| M5 — Capabilities ✓ | Vector-in-core (HNSW); compose better-auth / PostgREST / DuckDB | HNSW top-k matches brute force; MVCC-correct KNN | Platform grows by composition |
| M6 — SQL surface ✓ | Richer SQL frontend (6A–6E) — expressions, joins/aggregation, functions, constraints, dialect shims | Per-stage suites green; seam & ABI unmoved; reject-never-mis-parse | App-grade SQL parses & runs the same on Twill |
| M7 — Row-Level Security ✓ | In-core per-row enforcement (Phase 7); JWT identity composed around | Default-deny read/write enforcement; bypass off unless set; policies survive branch + replay | Supabase-style RLS that branches & scales-to-zero with the DB |
Design specs & status
The design specifications are the source of truth for why the engine is built the way it is. Each is tracked against its implementation status: ● Live shipped and gated by tests, ◐ In progress actively building, ○ Backlog proposed or planned. Implementation maps for shipped phases follow the table.
| # | Specification | Scope | Status |
|---|---|---|---|
| 01 | Architecture Overview | The three slots, the seam, dual delivery modes | ● Live |
| 02 | Engine Core | Parser → plan → executor, MVCC, WAL, C ABI | ● Live |
| 03 | Storage Interface | The narrow Storage trait — the seam | ● Live |
| 04 | Object-Storage Backend | LSM page store + S3-CAS commit log | ● Live |
| 05 | Local Cache | Shared-buffer cache keeping the hot path in-process | ● Live |
| 06 | Lifecycle & Controller | Cold start, idle stop, branch-on-LSN, fencing | ● Live |
| 07 | Server Mode & Wire Protocol | engine-server over pgwire (simple + extended) | ● Live |
| 08 | Bun Integration | Embedded via bun:ffi; server via Bun.sql | ● Live |
| 09 | Benchmark & Validation Plan | The five experiments locating W1 / W2 per tool | ◐ In progress |
| 10 | Hot-Row Contention Strategy | Serialize same-row writes; shard; route outliers | ● Live |
| 11 | Deployment Targets | Native (container) shipped; WASM/Workers exploratory | ◐ In progress |
| 12 | Capabilities: Build-in vs Compose | Vectors/HNSW in-core; auth/REST/OLAP composed around | ● Live |
| 13 | Roadmap & Build Sequence | The additive build order and milestones | ● Live |
| 14 | Tradeoffs & Risk Register | Write latency, single-writer ceiling, cold start | ● Live |
| 15 | Twill Bench CLI | Benchmark + correctness + serverless-efficiency CLI (all scenarios shipped) | ● Live |
| 16 | SQL Compatibility & Mapping | PostgreSQL/SQLite → Twill surface (Phase 6: 6A–6E live) | ● Live |
| 17 | Row-Level Security | In-core per-row enforcement (Phase 7); JWT identity composed around (epic #88) | ● Live |
| 18 | CLI Tooling | The twilldb scaffolder (new/init) + distribution | ● Live |
| 19 | Management CLI | Inspect / migrate / branch / serve over file:// & postgres:// | ● Live |
| 20 | Client Runtimes | @twilldb/node (koffi) + PHP FFI clients, Bun-parity | ● Live |
Implementation maps
Each shipped phase has a map tying the spec to the actual modules and tests. All ● Live.
| Phase | Map | Lands |
|---|---|---|
| 1 | Embedded Library | libengine + C ABI + LocalFileStorage + Bun client |
| 2 | Object Storage | ObjectStorage (LSM + S3-CAS) |
| 3 | Server + pgwire | engine-server |
| 4 | Branching & Lifecycle | BranchStorage + lease + twill-controller |
| 5 | Capabilities: Vector Search | vector(N) + HNSW + KNN |
| 6 | SQL Surface Completeness | SQL frontend 6A–6E (parser + executor only) |
How releases are versioned
Releases are versioned from the Cargo workspace version (Cargo.toml → [workspace.package] version). CI tags a release automatically on main once code quality, security, complexity, and unit tests are all green; the /release skill is the manual equivalent. Everything ships at one version, in lockstep.
How each release ships
One tag, three channels — matched to how you embed the engine. All travel at the same version, so the wrapper and the native binary it loads are always an ABI-matched pair.
| Channel | What ships | For |
|---|---|---|
| npm | @twilldb/bun + per-platform binary packages (@twilldb/engine-<os>-<cpu>) as optional dependencies | TypeScript / Bun apps — bun add @twilldb/bun, no build step |
| GitHub Releases | Prebuilt libengine.{so,dylib,dll} for each platform + the matching engine.h | Native / C-ABI embedders and the delivery backend the npm + container channels consume |
| GHCR | ghcr.io/bihaviour/twill-db — the engine-server (pgwire) container image, tagged per version and latest | Self-host / managed-service deployments behind a Postgres-wire listener |