Storage: file:// (local)
The pure-embedded backend (LocalFileStorage): a crash-safe local database file with zero network. It's the default for development and the fastest possible hot path — and it shares the exact engine, SQL, and API with the object-storage backends. See the shared model in the overview.
When to use it
- Development, tests, and CI (examples use
file://only). - Single-node apps that own their data.
- Offline / edge, where there is no object store to reach.
- Anywhere you want the lowest read/commit latency and no network at all.
Open it
import { open } from "@twilldb/bun";
using db = open("file://./app.db"); // relative path
// using db = open("file:///var/lib/twill/app.db"); // absolute path (three slashes)
# Same backend, served over the wire
cargo run -p twill-server -- --listen 127.0.0.1:5433 --db file://./srv.db
Breakdown: a relative file://./name resolves against the working directory; an absolute path uses three slashes (file:///abs/path). The scheme is the only thing that selects this backend.
Durability model
The WAL is written as CRC-checked, length-prefixed frames. On open after a crash, recovery replays the log and discards a torn trailing frame (a partially written final record), so every acknowledged commit survives — and a half-written one never corrupts state. A commit returns only after its records are fsync'd; there is no ack-from-buffer.
Gated by tests
This is enforced by the storage conformance suite (durability-after-ack, deterministic recovery, torn-trailing-frame), so the local backend's crash-safety is a tested property, not a hope.
The single-process rule
One process owns the file
A file:// database is owned by one process. Multiple connections within that process share one database (snapshot isolation holds across handles, via a process-global registry), but separate processes must not open the same file concurrently. For multi-client access, use server mode, or move to an object-storage backend where the durable single-writer lease coordinates instances.
Branching on file://
Branching still works locally: a branch's diverged writes go to a sibling file next to the base, while shared history is read from the base below the fork LSN. Creating a branch copies no pages. See Branching.
Moving to disaggregated later
Switching to object storage is a one-string change — your application code, SQL, and the C ABI are unchanged. Start here, and when you need stateless/scale-to-zero compute, point at s3://, r2://, or gs://.