At a glance

SchemeBackendDurability floorNetworkScale-to-zeroPage
file://LocalFileStorageLocal disk (CRC-checked WAL)Nonen/a (local)file://
s3://ObjectStorageS3 / S3-compatible (MinIO)Object APIYess3://
r2://ObjectStorageCloudflare R2Object API (zero egress)Yesr2://
gs://ObjectStorageGoogle Cloud StorageObject APIYesgs://

The promise

Move from a laptop file to global object storage by changing one string. There is no migration of application logic, no second engine, no different SQL. Durability is WAL-centric in every backend: a commit returns only after its records are durable.

What's shared across all backends

These hold no matter which scheme you choose — the backend pages only cover what differs.

  • Selection is the URL. open_storage dispatches on the scheme; unknown schemes are rejected, never silently defaulted.
  • Durability is WAL-centric. append_wal returns the commit LSN only after the records are durable — never an ack from a buffer.
  • MVCC read floor. A read at an LSN returns the greatest version at or below it; readers never block writers.
  • Branching & the lease are seam concerns. Copy-on-write branching and the durable single-writer lease are implemented at the storage seam, so they work the same way across backends (a sibling file for file://, a child key-prefix for object stores).

Credentials never go in the URL

Secrets live in the environment

Connection strings in code, tests, and examples should use file:// only. Real bucket credentials are environment configuration (provider variables), never the connection string or the repo. A secret-scanning hook and CI check exist to catch slips — treat a hit as a stop. Each object-storage page lists the exact variables for that provider.

Choose a backend

Twill DB documentation · Licensed under BUSL-1.1. · Author