Skip to Content
How it worksFormat versioning

Format versioning

A Larva store is shared mutable state between independently deployed clients — a web app, a cron job, a CLI on someone’s laptop — and they will never update in lockstep. Format versioning is what makes evolving the on-store layout safe anyway.

The formats

FormatWhat it added
1the original layout: manifest + chunks + history
2sequence columns (t.sequence()), auto-UUID columns (t.uuid()), and composite unique constraints — a store only declares 2 when its schema actually uses one, so plain stores stay readable by format-1 clients
3the ordered commit log — entered only by explicit db.upgrade()
4two-tier writes: per-writer intent queues + a lease. Constraint-free INSERTs (auto-generated id, no unique constraints) become durable at one PUT and fold into the log in the background — zero contention, read-your-writes preserved. Under cross-instance contention, ordered writes queue too and a lease-elected leader batches every waiting writer’s statement into one log slot, verdicts embedded in the entry. Entered by db.upgrade(); larva({ commitLog: true }) births new stores here

The guard

Every manifest read — current and history — validates formatVersion. A client that encounters a newer format than it supports refuses with a machine-readable error and touches nothing:

FORMAT_UNSUPPORTED: this database uses format version 3; this client supports up to 2 — upgrade with `npm install @larva-db/core@latest`

Why loud refusal matters: the failure mode of an unguarded old writer against a newer store isn’t an error — it’s silent. It would commit through the old protocol, bypassing the new format’s commit point, and destroy the no-lost-writes invariant without a sound. The guard turns a silent corruption into a one-line fix.

Upgrading

await db.upgrade(); // or: npx larva upgrade
  • One atomic commit — every client sees either the old world or the new one.
  • One-way and explicit — installing a newer package never changes any store’s format; only upgrade() does.
  • Idempotent — calling it on an already-upgraded store is a no-op.
  • Rollback-saferollbackTo across the upgrade boundary restores data while preserving the format, so rollback can never silently re-admit old writers.

Rolling out across several deployments: update the @larva-db/core dependency everywhere first (safe — changes nothing), then flip the store once.

Last updated on