Skip to content

Commit 798d17b

Browse files
bradleyshepgithub-advanced-security[bot]cloutiertyler
authored
Keynote Spacetime simulation comparisons (#4072)
# Description of Changes Adds a comprehensive benchmarking suite for comparing SpacetimeDB performance against other databases and backends. **Key features:** - Load testing framework that runs repeatable benchmarks across multiple connectors - Supports SpacetimeDB, PostgreSQL, CockroachDB, SQLite, Supabase, Convex, and Bun - Configurable test parameters: duration, concurrency, Zipf distribution (α) for hot/cold account skew - Outputs JSON reports with TPS and latency statistics to `./runs/` - Docker Compose support for containerized benchmarking - Includes a test SpacetimeDB Rust module (`modules/test-1/server`) **Connectors included:** - Direct SQL connectors (Postgres, CockroachDB, SQLite) - Drizzle ORM wrappers - RPC-based connectors for network-isolated benchmarking - SpacetimeDB WebSocket connector - Supabase and Convex cloud connectors # API and ABI breaking changes None. This is a new standalone template with no changes to existing code. # Expected complexity level and risk **1** - This is an additive change that introduces a new isolated template folder. It has no interactions with existing SpacetimeDB crates or modules. # Testing - [ ] Run `pnpm install` in `templates/keynote-2/` - [ ] Verify SpacetimeDB module compiles: `cd templates/keynote-2/modules/test-1/server && cargo build` - [ ] Run a basic benchmark against SpacetimeDB (requires local SpacetimeDB instance) --------- Signed-off-by: bradleyshep <148254416+bradleyshep@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: = <cloutiertyler@gmail.com>
1 parent c5b2d78 commit 798d17b

101 files changed

Lines changed: 16424 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

templates/keynote-2/.dockerignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules
2+
**/node_modules
3+
.git
4+
dist
5+
build
6+
.tmp

templates/keynote-2/.env.example

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# ===== Runtime toggles =====
2+
USE_DOCKER=1 # 1 = run docker compose up for pg/crdb; 0 = skip
3+
#SKIP_PG=1 # 1 = don't init Postgres in prep
4+
#SKIP_CRDB=1 # 1 = don't init Cockroach in prep
5+
#SKIP_SQLITE=1 # 1 = don't init SQLite in prep
6+
#SKIP_SUPABASE=1 # 1 = don't init Supabase in prep
7+
SKIP_CONVEX=1 # 1 = don't init Convex in prep
8+
USE_SPACETIME_METRICS_ENDPOINT=0
9+
10+
# ===== PostgreSQL =====
11+
POSTGRES_USER=postgres
12+
POSTGRES_PASSWORD=postgres
13+
POSTGRES_DB=postgres
14+
PG_URL=postgres://postgres:postgres@127.0.0.1:5432/postgres
15+
16+
# ===== CockroachDB =====
17+
CRDB_URL=postgresql://root@127.0.0.1:26257/defaultdb?sslmode=disable
18+
# Example managed CockroachDB URL (fill in your own values):
19+
#CRDB_URL=postgresql://username:password@your-cluster.region.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full
20+
21+
# ===== SQLite =====
22+
SQLITE_FILE=./.data/accounts.sqlite
23+
SQLITE_MODE=default
24+
25+
# ===== SpacetimeDB =====
26+
STDB_URL=ws://127.0.0.1:3000
27+
STDB_MODULE=test-1
28+
STDB_MODULE_PATH=./spacetimedb
29+
STDB_METRICS_URL=http://127.0.0.1:3000/v1/metrics
30+
31+
# ===== Supabase =====
32+
# Replace with your actual Supabase project ref
33+
SUPABASE_URL=http://127.0.0.1:54321
34+
SUPABASE_ANON_KEY=your_supabase_anon_key_here
35+
SUPABASE_DB_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
36+
37+
# ===== Convex =====
38+
#CONVEX_URL=https://your-deployment.convex.cloud
39+
CONVEX_URL=http://127.0.0.1:3210
40+
CONVEX_SITE_URL=http://127.0.0.1:3210
41+
CLEAR_CONVEX_ON_PREP=0
42+
CONVEX_USE_SHARDED_COUNTER=1
43+
44+
# ===== Bun =====
45+
BUN_URL=http://127.0.0.1:4001
46+
BUN_PG_URL=postgres://postgres:postgres@pg_bun:5432/bun_bench
47+
48+
# ===== RPC Servers =====
49+
PG_RPC_URL=http://127.0.0.1:4101
50+
CRDB_RPC_URL=http://127.0.0.1:4102
51+
SQLITE_RPC_URL=http://127.0.0.1:4103
52+
SUPABASE_RPC_URL=http://127.0.0.1:4106
53+
54+
# ===== PlanetScale (optional) =====
55+
#PLANETSCALE_PG_URL=postgresql://user:password@your-planetscale-host:5432/database
56+
#PLANETSCALE_RPC_URL=http://127.0.0.1:4104
57+
58+
# ===== Seeding knobs =====
59+
SEED_ACCOUNTS=100000
60+
SEED_INITIAL_BALANCE=10000000
61+
62+
VERIFY=0
63+
ENABLE_RPC_SERVERS=0

templates/keynote-2/.gitignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Environment files
2+
.env
3+
.env.*
4+
!.env.example
5+
6+
# Data files
7+
.data/
8+
9+
# Auto-generated files
10+
convex-app/convex/_generated/
11+
modules/test-1/module_bindings/
12+
13+
# SpacetimeDB
14+
.spacetime/
15+
16+
# Logs
17+
logs
18+
*.log
19+
npm-debug.log*
20+
yarn-debug.log*
21+
yarn-error.log*
22+
pnpm-debug.log*
23+
lerna-debug.log*
24+
25+
node_modules
26+
dist
27+
dist-ssr
28+
*.local
29+
30+
# Editor directories and files
31+
.vscode/
32+
.idea
33+
.DS_Store
34+
*.suo
35+
*.ntvs*
36+
*.njsproj
37+
*.sln
38+
*.sw?
39+
/runs

templates/keynote-2/.prettierrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"singleQuote": true,
3+
"printWidth": 80,
4+
"tabWidth": 2
5+
}

templates/keynote-2/DEVELOP.md

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
## Overview
2+
3+
This app runs repeatable load tests against multiple connectors (Bun+Postgres, CockroachDB, SQLite, Supabase, Convex, SpacetimeDB, etc.).
4+
5+
Each run:
6+
7+
- Loads a scenario from `src/tests/<test-name>/`
8+
- Runs it against one or more connectors
9+
- Writes a JSON report into `./runs/` with TPS and latency stats
10+
11+
---
12+
13+
## Demo Mode
14+
15+
Run a quick performance comparison:
16+
17+
```bash
18+
npm run demo
19+
```
20+
21+
The script will:
22+
23+
- Check that required services are running (prompts you to start them if not)
24+
- Seed databases with test data
25+
- Run benchmarks at high contention
26+
- Display animated results comparing your chosen systems (SpacetimeDB and Convex by default, as both are simple to run locally)
27+
28+
**Options:**
29+
30+
- `--seconds N` - Benchmark duration (default: 10)
31+
- `--concurrency N` - Concurrent connections (default: 50)
32+
- `--alpha N` - Contention level (default: 1.5)
33+
- `--systems a,b,c` - Systems to compare (default: convex,spacetimedb)
34+
- `--skip-prep` - Skip database seeding
35+
- `--no-animation` - Disable animated output
36+
37+
---
38+
39+
## Prerequisites
40+
41+
- **Node.js** ≥ 20.x
42+
- **pnpm** installed globally
43+
- **Docker** for local Postgres / Cockroach / Supabase
44+
- Local/Cloud Convex
45+
46+
From a fresh clone:
47+
48+
```bash
49+
pnpm install
50+
```
51+
52+
---
53+
54+
## Configuration (`.env`)
55+
56+
Copy `.env.example` to `.env` and adjust.
57+
58+
**Seeding / verification:**
59+
60+
- `SEED_ACCOUNTS` – number of accounts to seed (if unset, code defaults to `100_000`)
61+
- `SEED_INITIAL_BALANCE` – starting balance per account
62+
- `VERIFY` – enable extra verification passes when non-zero
63+
- `ENABLE_RPC_SERVERS` – flag used by scripts that start the RPC benchmark servers
64+
65+
**Runtime toggles:**
66+
67+
- `USE_DOCKER``1` = run Docker Compose for Postgres / CockroachDB; `0` = skip
68+
- `SKIP_PG``1` = don't init Postgres in prep
69+
- `SKIP_CRDB``1` = don't init CockroachDB in prep
70+
- `SKIP_SQLITE``1` = don't init SQLite in prep
71+
- `SKIP_SUPABASE``1` = don't init Supabase in prep
72+
- `SKIP_CONVEX``1` = don't init Convex in prep
73+
- `USE_SPACETIME_METRICS_ENDPOINT``1` = read committed transfer counts from the SpacetimeDB metrics endpoint; otherwise only local counters are used
74+
75+
**PostgreSQL / CockroachDB:**
76+
77+
- `PG_URL` – Postgres connection string
78+
- `CRDB_URL` – CockroachDB connection string
79+
80+
**SQLite:**
81+
82+
- `SQLITE_FILE` – path to the SQLite file
83+
- `SQLITE_MODE` – tuning preset for the SQLite connector
84+
85+
**SpacetimeDB:**
86+
87+
- `STDB_URL` – WebSocket URL for SpacetimeDB
88+
- `STDB_MODULE` – module name to load (e.g. `test-1`)
89+
- `STDB_MODULE_PATH` – filesystem path to the module source (for local dev)
90+
- `STDB_METRICS_URL` – HTTP URL for the SpacetimeDB metrics endpoint
91+
92+
**Supabase:**
93+
94+
- `SUPABASE_URL` – Supabase project URL
95+
- `SUPABASE_ANON_KEY` – Supabase anon/public key
96+
- `SUPABASE_DB_URL` – Postgres connection string for the Supabase database
97+
98+
**Convex:**
99+
100+
- `CONVEX_URL` – Convex deployment URL
101+
- `CONVEX_SITE_URL` – Convex site URL
102+
- `CLEAR_CONVEX_ON_PREP` – Convex prep flag (clears data when enabled)
103+
- `CONVEX_USE_SHARDED_COUNTER` – flag for using the sharded-counter implementation
104+
105+
**Bun / RPC helpers:**
106+
107+
- `BUN_URL` – Bun HTTP benchmark server URL
108+
- `BUN_PG_URL` – Postgres connection string for the Bun benchmark service
109+
110+
**RPC benchmark servers:**
111+
112+
- `PG_RPC_URL` – HTTP URL for the Postgres RPC server
113+
- `CRDB_RPC_URL` – HTTP URL for the CockroachDB RPC server
114+
- `SQLITE_RPC_URL` – HTTP URL for the SQLite RPC server
115+
116+
---
117+
118+
## Setup
119+
120+
### Generate bindings (first time after clone)
121+
122+
**SpacetimeDB module bindings:**
123+
124+
```bash
125+
cd spacetimedb
126+
spacetimedb generate --lang typescript --out-dir ../module_bindings
127+
cd ..
128+
```
129+
130+
**Convex generated files:**
131+
132+
```bash
133+
cd convex-app
134+
npx convex dev
135+
# Wait for it to generate files, then Ctrl+C
136+
cd ..
137+
```
138+
139+
### Start services
140+
141+
1. Start SpacetimeDB (`spacetimedb start`)
142+
2. Start Convex (inside convex-app run `npx convex dev`)
143+
3. Init Supabase (run `supabase init`) inside project root.
144+
4. `npm run prep` to seed the databases.
145+
5. `npm run bench` to run the test against all connectors.
146+
147+
## Commands & Examples
148+
149+
### 1. Run a test
150+
151+
```bash
152+
npm run bench [test-name] [--seconds N] [--concurrency N] [--alpha A] [--connectors list]
153+
```
154+
155+
Examples:
156+
157+
```bash
158+
# Default test (test-1), default args (note: only 1 test right now, and it's embedded)
159+
npm run bench
160+
161+
# Explicit test name
162+
npm run bench test-1
163+
164+
# Short run, 100 concurrent workers
165+
npm run bench test-1 --seconds 10 --concurrency 100
166+
167+
# Heavier skew on hot accounts
168+
npm run bench test-1 --alpha 2.0
169+
170+
# Only run selected connectors
171+
npm run bench test-1 --connectors spacetimedb,sqlite
172+
```
173+
174+
---
175+
176+
## CLI Arguments
177+
178+
From `src/cli.ts`:
179+
180+
- **`test-name`** (positional)
181+
- Name of the test folder under `src/tests/`
182+
- Default: `test-1`
183+
184+
- **`--seconds N`**
185+
- Duration of the benchmark in seconds
186+
- Default: `1`
187+
188+
- **`--concurrency N`**
189+
- Number of workers / in-flight operations
190+
- Default: `10`
191+
192+
- **`--alpha A`**
193+
- Zipf α parameter for account selection (hot vs cold distribution)
194+
- Default: `0.5`
195+
196+
- **`--connectors list`**
197+
- Optional, comma-separated list of connector `system` names
198+
- Example:
199+
200+
```bash
201+
--connectors spacetimedb,sqlite,postgres
202+
```
203+
204+
- If omitted, all connectors for that test are run
205+
- The valid names come from `tc.system` in the test modules and the keys in `CONNECTORS`
206+
207+
- **`--contention-tests startAlpha endAlpha step concurrency`**
208+
- Runs a sweep over Zipf α values for a single connector
209+
- Uses `startAlpha`, `endAlpha`, and `step` to choose the α values
210+
- Uses the provided `concurrency` for all runs
211+
212+
- **`--concurrency-tests startConc endConc step alpha`**
213+
- Runs a sweep over concurrency levels for a single connector
214+
- Uses `startConc`, `endConc`, and `step` to choose the concurrency values
215+
- Uses the provided `alpha` for all runs
216+
217+
---
218+
219+
### Running in Docker
220+
221+
You can also run the benchmark via Docker instead of Node directly:
222+
223+
```bash
224+
docker compose run --rm bench \
225+
--seconds 5 \
226+
--concurrency 50 \
227+
--alpha 1 \
228+
--connectors convex
229+
```
230+
231+
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.
232+
233+
## Output
234+
235+
Every run writes a JSON file into `./runs/`:
236+
237+
- Directory: `./runs/`
238+
- Filename: `<test-name>-<timestamp>.json`
239+
- Example: `test-1-2025-11-17T16-45-12-345Z.json`
240+
241+
Point your visualizations / CSV exports at `./runs/` and you’re good.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Dockerfile.bench
2+
FROM node:20.18.1-bookworm-slim
3+
4+
WORKDIR /app
5+
RUN npm install -g pnpm@9.15.3
6+
7+
# Install build tools for better-sqlite3
8+
RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/*
9+
10+
COPY package.json pnpm-lock.yaml* tsconfig.json* ./
11+
RUN pnpm install --frozen-lockfile || pnpm install
12+
13+
COPY src ./src
14+
COPY modules ./modules
15+
16+
# Correct: use bench script with passed args
17+
ENTRYPOINT ["pnpm", "tsx", "src/cli.ts"]

templates/keynote-2/Dockerfile.bun

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM oven/bun:latest
2+
3+
WORKDIR /app
4+
5+
COPY package.json bun.lockb* tsconfig.json ./
6+
7+
RUN bun install --ignore-scripts
8+
9+
# Copy source
10+
COPY bun ./bun
11+
12+
ENV PORT=4001
13+
14+
CMD ["bun", "bun/bun-server.ts"]

0 commit comments

Comments
 (0)