···2323just bench render-record 10 1000
2424just bench get-record 10 1000
2525just bench list-records 10 1000
2626+just bench repo-size 5000
2727+just bench repo-large 100000
2828+just bench space 1000
2629just bench http
2730just bench official-pds
2831just bench write-profile 10 500
···4750- `render-record`: DAG-CBOR decode plus JSON rendering, without SQLite.
4851- `get-record`: full `com.atproto.repo.getRecord` storage materialization.
4952- `list-records`: full `com.atproto.repo.listRecords` storage materialization.
5353+- `repo-size`: synthetic small/medium/large repo probes for
5454+ `listRecords(limit=100)` and full repo CAR materialization. The default Just
5555+ target keeps this moderate; use `repo-large` for intentional 100k+ record
5656+ runs.
5757+- `space`: experimental permissioned-data storage probes for space discovery,
5858+ private record writes, private record reads/lists, repo oplog catch-up, and
5959+ blob readback.
5060- `http`: starts a local ReleaseFast ZDS server and measures a seeded HTTP
5161 route matrix with ApacheBench. This is the route-level check for the `httpz`
5262 server boundary and should be tracked separately from storage
···6474access patterns introduced by the experimental `com.atproto.space.*` storage
6575model.
66766767-When adding the first permissioned-data probe, keep it out of `all` until the
6868-protocol shape settles. A useful first pass should seed one self-owned space,
6969-one writer repo, and one small blob, then measure these paths as distinct units
7070-of work:
7777+`just bench space` seeds one self-owned space, one writer repo, and one small
7878+blob, then measures these paths as distinct units of work:
71797272-- `createSpace`
7373-- `createRecord` or `applyWrites` into a space writer repo
8080+- `listSpaces`
8181+- `createRecord` into a space writer repo
7482- `getRecord` by `(space, repo, collection, rkey)`
7583- `listRecords`, limit 50, index-only response shape
7676-- ranged `getBlob`
8484+- `getBlob` storage readback
7785- `getRepoOplog` catch-up reads
78867987Comparison against Daniel's permissioned-data branch should live in this
8088section once we have a repeatable way to run that PDS locally. Until then, keep
8189ZDS numbers as local trend data and compare only equivalent operations.
82909191+## repo sizes
9292+9393+The normal write/read benchmarks use small synthetic repos so they stay fast
9494+enough to run while developing. `just bench repo-size` adds explicit
9595+small/medium/large tiers for repo-size-sensitive paths:
9696+9797+- small: 100 records
9898+- medium: 1,000 records, unless the selected maximum is lower
9999+- large: the `max_records` argument
100100+101101+Use `just bench repo-large 100000` for a deliberate larger run. Large public
102102+accounts are useful reference shapes because they stress repo export, record
103103+indexes, and cursor/list behavior. As of June 15, 2026, the public appview
104104+reports about 38k posts for `pfrazee.com` and about 87k posts for
105105+`jcsalterego.bsky.social`, so a 100k synthetic tier is the right order of
106106+magnitude for large-repo stress. Live network corpora should be captured into
107107+fixtures before they become stable benchmarks. Do not make routine CI or
108108+pre-commit checks depend on live PDS availability.
109109+83110## methodology
8411185112- Build ZDS with `-Doptimize=ReleaseFast`.
···152179| `getSession` | 19.9k req/s, p95 8 ms | 20.8k req/s, p95 6 ms |
153180| `listRecords`, limit 50 | 19.8k req/s, p95 11 ms | 22.4k req/s, p95 7 ms |
154181155155-## reference matrix
182182+## coverage map
183183+184184+High-level ZDS surface area represented in `bench/`:
185185+186186+| PDS surface | representative benchmark |
187187+|---|---|
188188+| repo writes | `write`, `metastore`, `write-profile` |
189189+| repo reads | `get-cid`, `get-block`, `get-record`, `list-records` |
190190+| repo export/sync snapshots | `repo`, `repo-size` |
191191+| sync event storage | `metastore` write path plus smoke tests |
192192+| blob storage | `blob`, `space` blob readback |
193193+| HTTP routing/serialization/auth overhead | `http` |
194194+| OAuth/session/account routes | `http` route matrix |
195195+| permissioned spaces | `space` |
196196+| official PDS read-path comparison | `official-pds` |
197197+198198+Still intentionally outside the routine benchmark gate:
199199+200200+- passkey ceremony cryptography and browser UX
201201+- mail delivery providers
202202+- live appview proxy latency
203203+- WebSocket subscriber fanout under network backpressure
204204+- live public-repo corpora until captured as stable fixtures
205205+206206+## implementation comparison
207207+208208+The main PDS implementations do not expose identical benchmark seams, so keep
209209+comparisons grouped by equivalent work:
210210+211211+| implementation | comparable bench surface | notes |
212212+|---|---|---|
213213+| ZDS | `bench/main.zig`, `tools/http_bench.sh` | local SQLite/blobstore, storage microbenchmarks, HTTP route matrix, permissioned-space storage |
214214+| Tranquil | `crates/tranquil-store/benches/metastore*.rs`, `blockstore.rs`, `eventlog.rs` | best match for metastore-shaped record/index/event/blockstore comparisons |
215215+| official Bluesky PDS | `bench/official-pds-records.bench.ts` copied into `packages/pds` | best match for actor-store record CID/get/list/write paths |
216216+| Pegasus | `pegasus/bench/bench_repository.ml`, `mist/bench/bench_mst.ml` | best match for repository block/MST internals; not a full HTTP/PDS route comparison yet |
156217157218Run Tranquil's metastore benchmark:
158219
+12
bench/justfile
···5757list-records callers="10" ops_per_caller="1000":
5858 {{zig}} build bench -Doptimize=ReleaseFast -- --scenario list-records --callers {{callers}} --ops-per-caller {{ops_per_caller}}
59596060+# benchmark listRecords and repo CAR materialization across synthetic repo sizes
6161+repo-size max_records="5000":
6262+ {{zig}} build bench -Doptimize=ReleaseFast -- --scenario repo-size --records {{max_records}}
6363+6464+# deliberately slow large-repo lane for Paul/Jerry-shaped synthetic repositories
6565+repo-large records="100000":
6666+ {{zig}} build bench -Doptimize=ReleaseFast -- --scenario repo-size --records {{records}}
6767+6868+# benchmark experimental permissioned-space storage paths
6969+space records="1000":
7070+ {{zig}} build bench -Doptimize=ReleaseFast -- --scenario space --records {{records}}
7171+6072# run the official Bluesky PDS read probe from a local atproto checkout
6173official-pds:
6274 ./run-official-pds.sh