templates/keynote-2/DEVELOP.md
This app runs repeatable load tests against multiple connectors (Bun+Postgres, CockroachDB, SQLite, Supabase, Convex, SpacetimeDB, etc.).
Each run:
src/tests/<test-name>/./runs/ with TPS and latency statsRun a quick performance comparison:
npm run demo
The script will:
Options:
--seconds N - Benchmark duration (default: 10)--concurrency N - Concurrent connections (default: 50)--alpha N - Contention level (default: 1.5)--systems a,b,c - Systems to compare (default: convex,spacetimedb)--skip-prep - Skip database seeding--no-animation - Disable animated outputFrom a fresh clone:
pnpm install
.env)Copy .env.example to .env and adjust.
Seeding / verification:
SEED_ACCOUNTS – number of accounts to seed (if unset, code defaults to 100_000)SEED_INITIAL_BALANCE – starting balance per accountVERIFY – enable extra verification passes when non-zeroENABLE_RPC_SERVERS – flag used by scripts that start the RPC benchmark serversRuntime toggles:
USE_DOCKER – 1 = run Docker Compose for Postgres / CockroachDB; 0 = skipSKIP_PG – 1 = don't init Postgres in prepSKIP_CRDB – 1 = don't init CockroachDB in prepSKIP_SQLITE – 1 = don't init SQLite in prepSKIP_SUPABASE – 1 = don't init Supabase in prepSKIP_CONVEX – 1 = don't init Convex in prepUSE_SPACETIME_METRICS_ENDPOINT – 1 = read committed transfer counts from the SpacetimeDB metrics endpoint; otherwise only local counters are usedPostgreSQL / CockroachDB:
PG_URL – Postgres connection stringCRDB_URL – CockroachDB connection stringSQLite:
SQLITE_FILE – path to the SQLite fileSQLITE_MODE – tuning preset for the SQLite connectorSpacetimeDB:
STDB_URL – WebSocket URL for SpacetimeDBSTDB_MODULE – module name to load (e.g. test-1)STDB_MODULE_PATH – filesystem path to the module source (for local dev)STDB_METRICS_URL – HTTP URL for the SpacetimeDB metrics endpointSTDB_CONFIRMED_READS – 1 = force confirmed reads on, 0 = force them offSupabase:
SUPABASE_URL – Supabase project URLSUPABASE_ANON_KEY – Supabase anon/public keySUPABASE_DB_URL – Postgres connection string for the Supabase databaseConvex:
CONVEX_URL – Convex deployment URLCONVEX_SITE_URL – Convex site URLCLEAR_CONVEX_ON_PREP – Convex prep flag (clears data when enabled)CONVEX_USE_SHARDED_COUNTER – flag for using the sharded-counter implementationPlanetScale:
PLANETSCALE_PG_URL – Postgres connection stringPLANETSCALE_RPC_URL – PlanetScale RPC server URL (default: http://127.0.0.1:4104)SKIP_PLANETSCALE_PG – 1 = skip PlanetScale in prepBun / RPC helpers:
BUN_URL – Bun HTTP benchmark server URLBUN_PG_URL – Postgres connection string for the Bun benchmark serviceRPC benchmark servers:
PG_RPC_URL – HTTP URL for the Postgres RPC serverCRDB_RPC_URL – HTTP URL for the CockroachDB RPC serverSQLITE_RPC_URL – HTTP URL for the SQLite RPC serverCreate a Postgres database on PlanetScale and set PLANETSCALE_PG_URL (and PLANETSCALE_RPC_URL if the RPC server runs elsewhere) in .env. Reported results used PS-2560 (32 vCPUs, 256 GB RAM).
SpacetimeDB module bindings:
cd spacetimedb
cargo run -p spacetimedb-cli -- generate --lang typescript --out-dir ../module_bindings --module-path . -y
cd ..
(Or use spacetime generate ... if the CLI is installed.)
Convex generated files:
cd convex-app
npx convex dev
# Wait for it to generate files, then Ctrl+C
cd ..
cargo run -p spacetimedb-cli -- start or spacetime start)npx convex dev)supabase init) inside project root.npm run prep to seed the databases.npm run bench to run the test against all connectors.npm run bench [test-name] [--seconds N] [--concurrency N] [--alpha A] [--connectors list]
Examples:
# Default test (test-1), default args (note: only 1 test right now, and it's embedded)
npm run bench
# Explicit test name
npm run bench test-1
# Short run, 100 concurrent workers
npm run bench test-1 --seconds 10 --concurrency 100
# Heavier skew on hot accounts
npm run bench test-1 --alpha 2.0
# Only run selected connectors
npm run bench test-1 --connectors spacetimedb,sqlite
From src/cli.ts:
test-name (positional)
src/tests/test-1--seconds N
1--concurrency N
10--alpha A
1.5--connectors list
Optional, comma-separated list of connector system names
Example:
--connectors spacetimedb,sqlite,postgres
If omitted, all connectors for that test are run
The valid names come from tc.system in the test modules and the keys in CONNECTORS
--contention-tests startAlpha endAlpha step concurrency
startAlpha, endAlpha, and step to choose the α valuesconcurrency for all runs--concurrency-tests startConc endConc step alpha
startConc, endConc, and step to choose the concurrency valuesalpha for all runsYou can also run the benchmark via Docker instead of Node directly:
docker compose run --rm bench \
--seconds 5 \
--concurrency 50 \
--alpha 1 \
--connectors convex
If using Docker, make sure to set USE_DOCKER=1 in .env, verify docker-compose env variables, verify you've run supabase init, and run npm prep before running bench.
Every run writes a JSON file into ./runs/:
./runs/<test-name>-<timestamp>.json
test-1-2025-11-17T16-45-12-345Z.jsonPoint your visualizations / CSV exports at ./runs/ and you’re good.