Current: v0.5.0

Releases & roadmap

Twill DB is built additively: the smallest embeddable thing first, then disaggregation, then server mode, then the lifecycle controller, then vector search, then SQL-surface completeness, now row-level security — each one a working, demonstrable capability. This page records what has shipped, what is planned next, and the status of every design specification. For the human-readable version history, see the Changelog.

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.

Status

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.

v0.5.0
current workspace version
ABI 3
frozen C embedding contract
Trait 3
storage seam version
7 / 7
phases shipped

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.rsexec.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-denyUSING 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

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.

At a glance

Milestone table

Each milestone is independently shippable and adds exactly one capability, because the seam below it never moves.

MilestoneHeadline deliverableGate(s)State after
M1 — Embedded libengine + engine.h + @twilldb/bun + LocalFileStorageBasic correctness + MVCC snapshotIn-process persistent DB, zero infra
M2 — Disaggregated ObjectStorage (LSM page store + S3-CAS log)Commit latency, group commit, durabilityDisaggregated + scale-to-zero, still embedded
M3 — Server engine-server + pgwire subset + pooler guidanceGroup-commit + contention in server modeMulti-client; PostgREST + Bun.sql for free
M4 — Controller Lifecycle state machine + branch-on-LSN + CAS fencingCold read + thundering-herdTrue scale-to-zero + instant clones
M5 — Capabilities Vector-in-core (HNSW); compose better-auth / PostgREST / DuckDBHNSW top-k matches brute force; MVCC-correct KNNPlatform grows by composition
M6 — SQL surface Richer SQL frontend (6A–6E) — expressions, joins/aggregation, functions, constraints, dialect shimsPer-stage suites green; seam & ABI unmoved; reject-never-mis-parseApp-grade SQL parses & runs the same on Twill
M7 — Row-Level Security In-core per-row enforcement (Phase 7); JWT identity composed aroundDefault-deny read/write enforcement; bypass off unless set; policies survive branch + replaySupabase-style RLS that branches & scales-to-zero with the DB
Specifications

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.

#SpecificationScopeStatus
01Architecture OverviewThe three slots, the seam, dual delivery modes● Live
02Engine CoreParser → plan → executor, MVCC, WAL, C ABI● Live
03Storage InterfaceThe narrow Storage trait — the seam● Live
04Object-Storage BackendLSM page store + S3-CAS commit log● Live
05Local CacheShared-buffer cache keeping the hot path in-process● Live
06Lifecycle & ControllerCold start, idle stop, branch-on-LSN, fencing● Live
07Server Mode & Wire Protocolengine-server over pgwire (simple + extended)● Live
08Bun IntegrationEmbedded via bun:ffi; server via Bun.sql● Live
09Benchmark & Validation PlanThe five experiments locating W1 / W2 per tool◐ In progress
10Hot-Row Contention StrategySerialize same-row writes; shard; route outliers● Live
11Deployment TargetsNative (container) shipped; WASM/Workers exploratory◐ In progress
12Capabilities: Build-in vs ComposeVectors/HNSW in-core; auth/REST/OLAP composed around● Live
13Roadmap & Build SequenceThe additive build order and milestones● Live
14Tradeoffs & Risk RegisterWrite latency, single-writer ceiling, cold start● Live
15Twill Bench CLIBenchmark + correctness + serverless-efficiency CLI (all scenarios shipped)● Live
16SQL Compatibility & MappingPostgreSQL/SQLite → Twill surface (Phase 6: 6A–6E live)● Live
17Row-Level SecurityIn-core per-row enforcement (Phase 7); JWT identity composed around (epic #88)● Live
18CLI ToolingThe twilldb scaffolder (new/init) + distribution● Live
19Management CLIInspect / migrate / branch / serve over file:// & postgres://● Live
20Client 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.

PhaseMapLands
1Embedded Librarylibengine + C ABI + LocalFileStorage + Bun client
2Object StorageObjectStorage (LSM + S3-CAS)
3Server + pgwireengine-server
4Branching & LifecycleBranchStorage + lease + twill-controller
5Capabilities: Vector Searchvector(N) + HNSW + KNN
6SQL Surface CompletenessSQL 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.

Distribution

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.

ChannelWhat shipsFor
npm@twilldb/bun + per-platform binary packages (@twilldb/engine-<os>-<cpu>) as optional dependenciesTypeScript / Bun apps — bun add @twilldb/bun, no build step
GitHub ReleasesPrebuilt libengine.{so,dylib,dll} for each platform + the matching engine.hNative / C-ABI embedders and the delivery backend the npm + container channels consume
GHCRghcr.io/bihaviour/twill-db — the engine-server (pgwire) container image, tagged per version and latestSelf-host / managed-service deployments behind a Postgres-wire listener