Skip to Content
The test lab

The test lab

This site doubles as a working demo and the project’s test bench. The lab runs a real Larva database — seeded customers, orders, and auto-numbered invoices, living in a private Vercel Blob store on format 3, the ordered commit log. Nothing is mocked.

The SQL console

Type any statement in the dialect and run it live. The example chips walk the breadth: joins + GROUP BY, zone-map-pruned date ranges, INSERT … RETURNING, revenue-by-day, HAVING + CASE, upserts, a sequence-numbered invoice, and one deliberately unsupported query so you can see an agent-grade error. Every result reports timing, chunks read vs. total (pruning, visibly), and the database version it saw.

Export buttons produce real files — the Postgres one loads with psql $DATABASE_URL < larva-demo.sql. Reset demo data re-seeds everything; mangle freely, that’s the point.

The data viewer

/viewer browses the same store visually: paged, sortable tables; a version scrubber that time-travels through every commit (asOf, live); and a chunk/zone-map internals panel powered by db.inspect(). Scrubbing is itself a demo of the architecture — watch a table grow from one chunk to several, and the format version flip, as history replays.

The stress lab

The bottom of the lab page hammers one database with concurrent writers, then audits the final state for lost updates, duplicates, and version drift — the commit protocol’s core promise, tested against the real store on every click.

  • append — disjoint writes; exercises the cheap rebase recovery path
  • counter — every write overlaps; forces full re-execute recovery
  • mixed — both at once

Guardrails (a public toy, not a public liability)

Storage is bounded per reset, and — the part a reset can’t launder — operations are bounded per day, because blob bills count both. All budget checks live server-side (app/lib/guard.ts) and fail closed.

  • Statements cap at 5,000 characters, and the console runs SELECT / INSERT / UPDATE / DELETE only. Schema statements (CREATE, ALTER, DROP, CREATE INDEX) are blocked — not for safety, but because they amplify the op count of every later commit. Clone the repo for the full dialect.
  • Row ceilings: 50 rows per INSERT, 2,000 rows per table (DEMO_TABLE_FULL → reset to continue).
  • Writes draw from a budget of 400 commits between resets — budget × statement cap bounds total storage no matter what the console is fed. Exhausting it returns WRITE_BUDGET_EXHAUSTED (HTTP 429); reset restarts it.
  • Global daily budgets, durable in the store itself and updated with the same CAS the commit protocol uses, shared across serverless instances: 600 console commits, 24 resets (with a 5-minute cooldown, so a reset loop can’t launder the write budget), and 30 stress runs — which also take a single-flight lease: one run at a time, abandoned leases expire on their own.
  • Per-IP rate limits on every endpoint (reads included), and browser writes from foreign origins are refused outright.
  • Stress runs always clean up after themselves, and reset also sweeps blobs left by failed harness runs.

API routes (what the buttons call)

RouteMethodDoes
/api/sqlPOST { sql, allowFullTable? }run one statement, return rows + stats
/api/export?format=postgres|jsonGETdownload the live database
/api/export?format=csv&table=NAMEGETdownload one table as CSV
/api/demo-resetPOSTdrop and re-seed; restarts the write budget
/api/stressPOST { writers, commitsPerWriter, mode }run the concurrent-writer audit

Run your own

git clone https://github.com/pango07/larva-db && cd larva-db bun install vercel link vercel blob store add my-larva-store --access private --yes vercel env pull .env.local # BLOB_READ_WRITE_TOKEN bun run dev # http://localhost:3000 vercel deploy --prod --yes # or ship it

The test suites — 318 checks across eight suites

Correctness risk concentrates in the conflict/retry path, so that’s where the tests concentrate. All of it runs in CI on every push; merges to main publish to npm.

bunx tsc --noEmit # typecheck (includes compile-only type tests) bun run lint # offline — no credentials needed bun scripts/s3-adapter-test.ts # storage contract + injected 409/500 chaos bun scripts/group-commit-test.ts # coalescing, conflict matrix, formats 3–4, upgrade flow bun scripts/guard-test.ts # the demo-endpoint abuse guards above # live — need BLOB_READ_WRITE_TOKEN in .env.local bun scripts/sql-smoke.ts # the whole dialect, end to end bun scripts/api-smoke.ts # transactions, exports, vacuum bun scripts/cli-smoke.ts # the larva CLI as a subprocess bun scripts/stress.ts --writers 4 --commits 6 # add --log for format 3 bun scripts/property.ts --writers 4 --ops 10 # add --log for format 3 bun scripts/bench.ts # write throughput, both formats
SuiteWhat it proves
stress.tsconcurrent writers on a real store: zero lost updates, exact version arithmetic
property.tsrandomized workloads verified against a per-writer sequential model
sql-smoke.tsthe full dialect + the machine-readable error catalog + pruning + time travel
api-smoke.tstransaction atomicity, export round-trips, vacuum retention, format 3 live
cli-smoke.tsthe CLI: arguments, exit codes, files on disk, upgrade/rollback
s3-adapter-test.tsthe storage contract under injected chaos
group-commit-test.tscoalescing, the conflict matrix, the ordered commit log under chaos
guard-test.tsthe public lab’s abuse guards: budgets count exactly under CAS contention, fail closed

The stress and property harnesses ship in the package — import { runStress, runProperty } from "@larva-db/core/testing" — so you can gauntlet your own setup.

Last updated on