FireTrident: a colony, not a queue

Scaling benchmark, 2026-10-12. Live runs with real Artifacts commits (the serial trunk writer on the production deployment; group commit and the scale runs on preview deployments) and a discrete-event simulator calibrated on them, comparing FireTrident with the common design: exclusive file locks plus one serialized merge queue. Every chart and tile says whether its points are MEASURED or SIMULATED, and every count of failed calls names its run.

MEASURED
After the scale fixes, measured peak
2,924/min
1,000 synthetic agents (no model calls, review off); 2,714/min at 2,000; 2,778/min at 5,000. Failed calls in these runs: 0 at 1,000 and 2,000 agents, 0.15% at 5,000
MEASURED
Lineage notes after the scale runs
5,894/5,894
landing commits on the scale colony's trunk with a note, read with stock git (0 without)
MEASURED
Group commit run, measured peak
690/min
200 agents: 5.5× the serial writer's 126/min; 1,000 agents 515/min (3.7×, stopped early: coordinator overload). Preview, before the scale fixes
MEASURED
Serial trunk writer run, measured peak
138/min
production, 1,000 agents: 0 of 29,307 calls failed
SIMULATED
Baseline ceiling, same costs
58/min
locks + one merge queue, live workload
SIMULATED
Serial trunk writer vs baseline
2.5× · 1.6×
live workload · hono workload, 1,000 agents
SIMULATED
Group commit vs baseline
12× · 4×
simulator; same two workloads
SIMULATED
When checks take 30 s
45×
hono, 1,000 agents: the queue retests serially
MEASURED
Cascade detected and damped
σ 30
1 landing, 30 stale returns; σ < 1 in 40 s

Throughput on the live workloadMEASUREDSIMULATED

Synthetic agents on the production deployment with the serial trunk writer, 4 runs at 10 to 1,000 concurrent agents. Each change adds one file in one of 64 directories, and every landing is a real trunk commit pushed with compare-and-swap. The lines are the simulator replaying the same workload with costs fitted to these runs: it lands within about 10% of every measured point.

Trunk group commit, built and MEASURED (2026-10-12-g1, on a preview deployment, before the scale fixes). The trunk writer now takes every lane batch that queued while its previous cycle ran: it re-validates each proposal against trunk and against the batches ahead of it, builds one commit per batch chained on the one before (so lineage and why stay per landing), pushes trunk once and all lineage notes once. Same driver, same workload: 10 agents 216/min (serial writer 92/min), 200 agents 690/min (serial writer 126/min), 1,000 agents 515/min (serial writer 138/min), stopped early by the driver's error guard.

FireTrident, serial trunk writer, MEASURED liveFireTrident + trunk group commit, MEASURED liveFireTrident, serial trunk writer, SIMULATEDBaseline: locks + one merge queue, SIMULATEDFireTrident + trunk group commit, SIMULATED
020040060080010501002005001,000concurrent agents (log scale)landed changes per minuteSIMULATED · FireTrident + trunk group commit · 10 agents: 212.9 landed/min (mean of 3 seeds, 212.9–212.9)SIMULATED · FireTrident + trunk group commit · 50 agents: 501.0 landed/min (mean of 3 seeds, 493.2–512.5)SIMULATED · FireTrident + trunk group commit · 200 agents: 680.8 landed/min (mean of 3 seeds, 652.4–703.9)SIMULATED · FireTrident + trunk group commit · 1,000 agents: 712.0 landed/min (mean of 3 seeds, 711.7–712.6)group commit (sim)SIMULATED · Baseline: file locks + one merge queue · 10 agents: 57.6 landed/min (mean of 3 seeds, 57.6–57.6)SIMULATED · Baseline: file locks + one merge queue · 50 agents: 56.9 landed/min (mean of 3 seeds, 56.9–56.9)SIMULATED · Baseline: file locks + one merge queue · 200 agents: 57.5 landed/min (mean of 3 seeds, 57.5–57.5)SIMULATED · Baseline: file locks + one merge queue · 1,000 agents: 57.2 landed/min (mean of 3 seeds, 57.2–57.2)BaselineSIMULATED · FireTrident with the serial trunk writer · 10 agents: 85.7 landed/min (mean of 3 seeds, 85.7–85.7)SIMULATED · FireTrident with the serial trunk writer · 50 agents: 86.4 landed/min (mean of 3 seeds, 86.4–86.4)SIMULATED · FireTrident with the serial trunk writer · 200 agents: 138.0 landed/min (mean of 3 seeds, 137.7–138.6)SIMULATED · FireTrident with the serial trunk writer · 1,000 agents: 144.9 landed/min (mean of 3 seeds, 144.9–144.9)serial writer (sim)92MEASURED · FireTrident live, serial trunk writer · 10 agents: 92.4 landed changes/min (92.4 commits/min, batch 1.00), time-to-land p50 4.1 s84MEASURED · FireTrident live, serial trunk writer · 50 agents: 84.4 landed changes/min (84.4 commits/min, batch 1.01), time-to-land p50 24.7 s126MEASURED · FireTrident live, serial trunk writer · 200 agents: 125.9 landed changes/min (71.8 commits/min, batch 1.47), time-to-land p50 54.3 s138MEASURED · FireTrident live, serial trunk writer · 1000 agents: 138.5 landed changes/min (63.7 commits/min, batch 1.99), time-to-land p50 61.6 s216MEASURED · FireTrident live with trunk group commit · 10 agents: 215.6 landed changes/min (211.6 commits/min, batch 1.02), time-to-land p50 0.8 s690MEASURED · FireTrident live with trunk group commit · 200 agents: 690.4 landed changes/min (589.9 commits/min, batch 1.22), time-to-land p50 2.9 s515MEASURED · FireTrident live with trunk group commit · 1000 agents: 515.1 landed changes/min (369.2 commits/min, batch 1.41), time-to-land p50 4.8 sgroup commit (measured)

Scale: 1,000 to 5,000 agents on one colonyMEASURED

These are synthetic agents: no model calls, no agent-side git and no work time, with the review layer turned off on the colony (POST /api/colonies/:id/decide/policy {"enabled":false}), so the runs measure coordination and landing only. Same driver and workload as above: each change adds one file in one of 64 directories, and every landing is a real Artifacts commit pushed with compare-and-swap. 120 s per run with a 10 s ramp; outcomes reach the agents over the live WebSocket with a 20 s fallback poll; group commit on; one colony (g6-scale5k) on a preview deployment with its own Durable Objects and a pre-forked workspace pool. Raw runs: ../2026-10-12-scale/.

What changed since the group-commit run: takes share one read of each region's claims, at most 128 takes score at once and waiting agents are paced, outcomes are pushed to agents instead of polled, stopped agents release their claims at once, leasing a workspace is pure SQL with one token kept per slot, and lineage notes use git's two-character fanout (docs/ARCHITECTURE.md, Scale).

group commit before the scale fixes, MEASURED (preview)group commit after the scale fixes, MEASURED (preview)
08001.6K2.4K3.2K4K101002001,0002,0005,000concurrent agents (log scale)landed changes per minuteMEASURED · group commit run, before the scale fixes (preview) · 10 agents: 215.6 landed/min; 0 of 732 calls failed690MEASURED · group commit run, before the scale fixes (preview) · 200 agents: 690.4 landed/min; 22 of 7,429 calls failed (0.30%)515MEASURED · group commit run, before the scale fixes (preview) · 1,000 agents: 515.1 landed/min; 816 of 9,927 calls failed (8.22%); stopped early (error rate 38% over 5 s at 60 s)before the fixes2,924MEASURED · scale run, after the scale fixes (preview) · 1,000 agents: 2923.6 landed/min, time to land p50 13.0 s; 0 of 31,308 calls failed2,714MEASURED · scale run, after the scale fixes (preview) · 2,000 agents: 2713.9 landed/min, time to land p50 14.8 s; 0 of 45,034 calls failed2,778MEASURED · scale run, after the scale fixes (preview) · 5,000 agents: 2777.7 landed/min, time to land p50 12.5 s; 78 of 50,368 calls failed (0.15%), all in the first 33 safter the fixes

Scale runs (MEASURED). ttl: time to land. cycle, proposals/cycle, queue (waiting for the trunk writer), pull (proposal blobs from workspace forks) and push: trunk writer medians over the steady window

agentslanded/mincommits/minttl p50/p90/p99 stake p50/p99 mscycle sproposals/cyclequeue spull spush scallsfailed
1,0002,92447313.0 / 17.0 / 20.9580 / 5,2513.51965.71.81.131,3080
2,0002,71445114.8 / 19.5 / 23.0570 / 1,9793.91955.92.21.245,0340
5,0002,77846812.5 / 17.4 / 27.2653 / 3,9603.41966.02.21.050,36878

Failed calls, per run. 1,000 agents: 0 of 31,308 calls failed. 2,000 agents: 0 of 45,034 calls failed. 5,000 agents: 78 of 50,368 calls failed (0.15%), all in the first 33 s. The error kinds the driver recorded (it keeps the first eight distinct messages) are connection failures on the bench client (ENOTFOUND, ECONNRESET, UND_ERR_CONNECT_TIMEOUT), while one bench machine held up to 3,597 open sockets around the end of the ramp, and the service answering 500 Durable Object reset because its code was updated. (a Durable Object restarting on newly deployed code).

Lineage. After the runs, stock git fetched trunk and refs/notes/firetrident from colony g6-scale5k's Artifacts repository: 5,894 of 5,894 landing commits carry a lineage note (0 without), 60 sampled git notes show name their landing (0 mismatches), and the notes tree is 256 two-character fanout directories with 0 flat notes.

Next limit. The next limit is TrunkDO, the single trunk writer. Each commit cycle took 3.4–3.9 s at the median and carried 195–196 proposals, against its cap of 200 (CYCLE_MAX_PROPOSALS), so throughput is flat past 1,000 agents: 2,714–2,924 landings/min from 1,000 to 5,000 agents. About 6 s of queueing for the writer (5.7–6.0 s p50) dominates time to land (12.5–14.8 s p50). Inside a cycle, reading proposal blobs out of workspace forks takes longest (1.8–2.2 s p50), then the trunk push (1.0–1.2 s).

Earlier runs on the same colony, not in the table: 3,485/min at 1,000 agents and 3,342/min at 2,000 agents with the build before the take gate; the trunk cycle grew from 2.9 s to 3.9 s p50 over the 5 completed runs as the bench's trunk tree grew (each intent adds a file). 2 attempts at 5,000 agents stopped early: build before the take gate (10:56Z): ColonyDO isolate exceeded its memory limit about 20 s in (thousands of takes in flight, each holding up to 200 scored candidates) (error rate 84% over 5 s at 20 s); and take gate build, started 1.5 min after its deploy: a burst of dropped connections (cause not recorded yet) and 'reset because its code was updated' tripped the guard at 15 s (error rate 35% over 5 s at 15 s). summary.json records all of them; their raw files were not kept.

Throughput from 10 to 100,000 agents on hono's historySIMULATED

Write sets drawn from 2285 real changes to honojs/hono, grown along co-change edges. Read sets are the written files' direct imports. The repo is a monorepo of 100 copies (regions at depth 3), and agents work a log-normal median of 60 s per change. Mean of 3 seeds; hover a point for the seed range.

FireTrident, serial trunk writerBaseline: locks + one merge queueFireTrident + trunk group commit
050100150200250101001K10K100Kconcurrent agents (log scale)landed changes per minuteSIMULATED · FireTrident + trunk group commit · 10 agents: 6.6 landed/min (mean of 3 seeds, 5.7–7.2)SIMULATED · FireTrident + trunk group commit · 100 agents: 62.0 landed/min (mean of 3 seeds, 61.3–63.4)SIMULATED · FireTrident + trunk group commit · 1,000 agents: 204.5 landed/min (mean of 3 seeds, 197.3–213.1)SIMULATED · FireTrident + trunk group commit · 10,000 agents: 205.6 landed/min (mean of 3 seeds, 202.5–211.1)SIMULATED · FireTrident + trunk group commit · 100,000 agents: 207.2 landed/min (mean of 3 seeds, 193.7–228.8)+ group commitSIMULATED · Baseline: file locks + one merge queue · 10 agents: 6.6 landed/min (mean of 3 seeds, 5.7–7.2)SIMULATED · Baseline: file locks + one merge queue · 100 agents: 56.2 landed/min (mean of 3 seeds, 56.1–56.3)SIMULATED · Baseline: file locks + one merge queue · 1,000 agents: 51.9 landed/min (mean of 3 seeds, 51.3–52.3)SIMULATED · Baseline: file locks + one merge queue · 10,000 agents: 51.9 landed/min (mean of 3 seeds, 51.3–52.3)SIMULATED · Baseline: file locks + one merge queue · 100,000 agents: 51.9 landed/min (mean of 3 seeds, 51.3–52.3)BaselineSIMULATED · FireTrident with the serial trunk writer · 10 agents: 6.6 landed/min (mean of 3 seeds, 5.7–7.2)SIMULATED · FireTrident with the serial trunk writer · 100 agents: 62.1 landed/min (mean of 3 seeds, 62.0–62.2)SIMULATED · FireTrident with the serial trunk writer · 1,000 agents: 85.6 landed/min (mean of 3 seeds, 85.4–85.9)SIMULATED · FireTrident with the serial trunk writer · 10,000 agents: 85.8 landed/min (mean of 3 seeds, 85.5–86.0)SIMULATED · FireTrident with the serial trunk writer · 100,000 agents: 85.8 landed/min (mean of 3 seeds, 85.1–86.3)serial writer

Wasted work: rework % of all work time

015304560101001K10K100Kagents (log)rework %SIMULATED · FireTrident + trunk group commit · 10 agents: 0.4 % (mean of 3 seeds, 0.0–0.7)SIMULATED · FireTrident + trunk group commit · 100 agents: 12.7 % (mean of 3 seeds, 10.7–14.8)SIMULATED · FireTrident + trunk group commit · 1,000 agents: 45.3 % (mean of 3 seeds, 44.4–46.7)SIMULATED · FireTrident + trunk group commit · 10,000 agents: 46.9 % (mean of 3 seeds, 46.1–48.0)SIMULATED · FireTrident + trunk group commit · 100,000 agents: 45.7 % (mean of 3 seeds, 44.9–46.9)SIMULATED · Baseline: file locks + one merge queue · 10 agents: 0.1 % (mean of 3 seeds, 0.0–0.4)SIMULATED · Baseline: file locks + one merge queue · 100 agents: 5.7 % (mean of 3 seeds, 5.2–6.0)SIMULATED · Baseline: file locks + one merge queue · 1,000 agents: 21.7 % (mean of 3 seeds, 20.8–22.1)SIMULATED · Baseline: file locks + one merge queue · 10,000 agents: 21.7 % (mean of 3 seeds, 20.8–22.1)SIMULATED · Baseline: file locks + one merge queue · 100,000 agents: 21.7 % (mean of 3 seeds, 20.4–22.6)SIMULATED · FireTrident with the serial trunk writer · 10 agents: 0.4 % (mean of 3 seeds, 0.0–0.7)SIMULATED · FireTrident with the serial trunk writer · 100 agents: 12.3 % (mean of 3 seeds, 11.0–13.3)SIMULATED · FireTrident with the serial trunk writer · 1,000 agents: 42.5 % (mean of 3 seeds, 41.4–44.1)SIMULATED · FireTrident with the serial trunk writer · 10,000 agents: 41.4 % (mean of 3 seeds, 40.1–43.2)SIMULATED · FireTrident with the serial trunk writer · 100,000 agents: 41.9 % (mean of 3 seeds, 40.0–45.3)

Time to land, p99 (s, submit to landing)

03006009001.2K101001K10K100Kagents (log)secondsSIMULATED · FireTrident + trunk group commit · 10 agents: 14.3 s (mean of 3 seeds, 1.2–40.2)SIMULATED · FireTrident + trunk group commit · 100 agents: 212.4 s (mean of 3 seeds, 191.7–238.4)SIMULATED · FireTrident + trunk group commit · 1,000 agents: 651.1 s (mean of 3 seeds, 616.6–695.2)SIMULATED · FireTrident + trunk group commit · 10,000 agents: 655.0 s (mean of 3 seeds, 620.9–695.1)SIMULATED · FireTrident + trunk group commit · 100,000 agents: 636.4 s (mean of 3 seeds, 600.8–664.9)SIMULATED · Baseline: file locks + one merge queue · 10 agents: 2.2 s (mean of 3 seeds, 1.9–2.5)SIMULATED · Baseline: file locks + one merge queue · 100 agents: 141.9 s (mean of 3 seeds, 134.2–156.2)SIMULATED · Baseline: file locks + one merge queue · 1,000 agents: 1018.0 s (mean of 3 seeds, 1004.3–1030.2)SIMULATED · Baseline: file locks + one merge queue · 10,000 agents: 1018.0 s (mean of 3 seeds, 1004.3–1030.2)SIMULATED · Baseline: file locks + one merge queue · 100,000 agents: 1021.2 s (mean of 3 seeds, 1005.8–1037.8)SIMULATED · FireTrident with the serial trunk writer · 10 agents: 14.3 s (mean of 3 seeds, 1.2–40.2)SIMULATED · FireTrident with the serial trunk writer · 100 agents: 204.1 s (mean of 3 seeds, 194.5–209.2)SIMULATED · FireTrident with the serial trunk writer · 1,000 agents: 974.5 s (mean of 3 seeds, 958.1–984.4)SIMULATED · FireTrident with the serial trunk writer · 10,000 agents: 935.7 s (mean of 3 seeds, 887.2–962.1)SIMULATED · FireTrident with the serial trunk writer · 100,000 agents: 964.6 s (mean of 3 seeds, 954.7–981.8)

Conflicts per 1,000 submitted changes

0150300450101001K10K100Kagents (log)per 1,000SIMULATED · FireTrident + trunk group commit · 10 agents: 7 per 1,000 (mean of 3 seeds, 0–12)SIMULATED · FireTrident + trunk group commit · 100 agents: 77 per 1,000 (mean of 3 seeds, 69–83)SIMULATED · FireTrident + trunk group commit · 1,000 agents: 319 per 1,000 (mean of 3 seeds, 308–333)SIMULATED · FireTrident + trunk group commit · 10,000 agents: 333 per 1,000 (mean of 3 seeds, 321–342)SIMULATED · FireTrident + trunk group commit · 100,000 agents: 322 per 1,000 (mean of 3 seeds, 317–326)SIMULATED · Baseline: file locks + one merge queue · 10 agents: 3 per 1,000 (mean of 3 seeds, 0–10)SIMULATED · Baseline: file locks + one merge queue · 100 agents: 72 per 1,000 (mean of 3 seeds, 67–77)SIMULATED · Baseline: file locks + one merge queue · 1,000 agents: 318 per 1,000 (mean of 3 seeds, 316–320)SIMULATED · Baseline: file locks + one merge queue · 10,000 agents: 318 per 1,000 (mean of 3 seeds, 316–320)SIMULATED · Baseline: file locks + one merge queue · 100,000 agents: 315 per 1,000 (mean of 3 seeds, 310–323)SIMULATED · FireTrident with the serial trunk writer · 10 agents: 7 per 1,000 (mean of 3 seeds, 0–12)SIMULATED · FireTrident with the serial trunk writer · 100 agents: 75 per 1,000 (mean of 3 seeds, 70–78)SIMULATED · FireTrident with the serial trunk writer · 1,000 agents: 397 per 1,000 (mean of 3 seeds, 384–416)SIMULATED · FireTrident with the serial trunk writer · 10,000 agents: 386 per 1,000 (mean of 3 seeds, 371–401)SIMULATED · FireTrident with the serial trunk writer · 100,000 agents: 389 per 1,000 (mean of 3 seeds, 365–415)

Coordination messages per landed change (log)

1101001K10K101001K10K100Kagents (log)messagesSIMULATED · FireTrident + trunk group commit · 10 agents: 322 messages (mean of 3 seeds, 316–331)SIMULATED · FireTrident + trunk group commit · 100 agents: 295 messages (mean of 3 seeds, 289–302)SIMULATED · FireTrident + trunk group commit · 1,000 agents: 670 messages (mean of 3 seeds, 647–700)SIMULATED · FireTrident + trunk group commit · 10,000 agents: 2145 messages (mean of 3 seeds, 2127–2171)SIMULATED · FireTrident + trunk group commit · 100,000 agents: 17131 messages (mean of 3 seeds, 15470–18198)SIMULATED · Baseline: file locks + one merge queue · 10 agents: 8 messages (mean of 3 seeds, 7–8)SIMULATED · Baseline: file locks + one merge queue · 100 agents: 12 messages (mean of 3 seeds, 12–12)SIMULATED · Baseline: file locks + one merge queue · 1,000 agents: 223 messages (mean of 3 seeds, 217–227)SIMULATED · Baseline: file locks + one merge queue · 10,000 agents: 3425 messages (mean of 3 seeds, 3406–3459)SIMULATED · Baseline: file locks + one merge queue · 100,000 agents: 35419 messages (mean of 3 seeds, 35152–35828)SIMULATED · FireTrident with the serial trunk writer · 10 agents: 324 messages (mean of 3 seeds, 316–331)SIMULATED · FireTrident with the serial trunk writer · 100 agents: 294 messages (mean of 3 seeds, 292–296)SIMULATED · FireTrident with the serial trunk writer · 1,000 agents: 1391 messages (mean of 3 seeds, 1289–1501)SIMULATED · FireTrident with the serial trunk writer · 10,000 agents: 5022 messages (mean of 3 seeds, 4876–5179)SIMULATED · FireTrident with the serial trunk writer · 100,000 agents: 40683 messages (mean of 3 seeds, 39709–41401)

The seizure detector: one landing, 30 stale returnsMEASURED

Live, colony bench-w2-cascade. 30 agents in src/core read src/core/config.ts and kept working. A real commit to that file landed, and all 30 in-flight proposals came back stale, each attributed to that one landing. σ jumped to 30, so the lane's cadence stretched from 1 s to 8 s. The reworked proposals then landed in inhibited batches until σ fell below 1. σ points are the sigma events on /api/colonies/:id/live; the line is GET /field polled every second.

σ events on the live WebSocketσ polled from /field
σ > 1: governor engaged0510152025300+10+20+30+40+50+60+70+80+90seconds after the landing of src/core/config.tsσ (stale returns per landed change)σ = 1MEASURED (polled /field) · σ at +-8.7 s: 0.00MEASURED (polled /field) · σ at +-7.7 s: 0.00MEASURED (polled /field) · σ at +-6.6 s: 0.00MEASURED (polled /field) · σ at +-5.5 s: 0.00MEASURED (polled /field) · σ at +-4.5 s: 0.00MEASURED (polled /field) · σ at +-3.2 s: 0.00MEASURED (polled /field) · σ at +-2.1 s: 0.00MEASURED (polled /field) · σ at +-1.1 s: 0.00MEASURED (polled /field) · σ at +0.0 s: 0.00MEASURED (polled /field) · σ at +1.1 s: 0.00MEASURED (polled /field) · σ at +2.1 s: 0.00MEASURED (polled /field) · σ at +3.2 s: 0.00MEASURED (polled /field) · σ at +4.3 s: 0.00MEASURED (polled /field) · σ at +5.3 s: 30.00MEASURED (polled /field) · σ at +6.4 s: 30.00MEASURED (polled /field) · σ at +7.5 s: 30.00MEASURED (polled /field) · σ at +8.5 s: 30.00MEASURED (polled /field) · σ at +9.6 s: 30.00MEASURED (polled /field) · σ at +11.0 s: 30.00MEASURED (polled /field) · σ at +12.1 s: 30.00MEASURED (polled /field) · σ at +13.1 s: 30.00MEASURED (polled /field) · σ at +14.2 s: 30.00MEASURED (polled /field) · σ at +15.3 s: 30.00MEASURED (polled /field) · σ at +16.3 s: 10.00MEASURED (polled /field) · σ at +17.4 s: 10.00MEASURED (polled /field) · σ at +18.5 s: 10.00MEASURED (polled /field) · σ at +19.5 s: 10.00MEASURED (polled /field) · σ at +20.6 s: 10.00MEASURED (polled /field) · σ at +21.7 s: 10.00MEASURED (polled /field) · σ at +22.8 s: 10.00MEASURED (polled /field) · σ at +24.0 s: 10.00MEASURED (polled /field) · σ at +25.2 s: 2.00MEASURED (polled /field) · σ at +26.2 s: 2.00MEASURED (polled /field) · σ at +27.3 s: 2.00MEASURED (polled /field) · σ at +28.4 s: 2.00MEASURED (polled /field) · σ at +29.8 s: 2.00MEASURED (polled /field) · σ at +30.9 s: 2.00MEASURED (polled /field) · σ at +32.0 s: 2.00MEASURED (polled /field) · σ at +33.0 s: 1.11MEASURED (polled /field) · σ at +34.1 s: 1.11MEASURED (polled /field) · σ at +35.2 s: 1.03MEASURED (polled /field) · σ at +36.2 s: 1.03MEASURED (polled /field) · σ at +37.3 s: 1.03MEASURED (polled /field) · σ at +38.4 s: 1.03MEASURED (polled /field) · σ at +39.4 s: 0.97MEASURED (polled /field) · σ at +40.5 s: 0.97MEASURED (polled /field) · σ at +41.6 s: 0.97MEASURED (polled /field) · σ at +42.6 s: 0.97MEASURED (polled /field) · σ at +43.7 s: 0.97MEASURED (polled /field) · σ at +45.1 s: 0.97MEASURED (polled /field) · σ at +46.2 s: 0.97MEASURED (polled /field) · σ at +47.2 s: 0.97MEASURED (polled /field) · σ at +48.3 s: 0.97MEASURED (polled /field) · σ at +49.4 s: 0.97MEASURED (polled /field) · σ at +50.5 s: 0.97MEASURED (polled /field) · σ at +51.5 s: 0.97MEASURED (polled /field) · σ at +52.6 s: 0.97MEASURED (polled /field) · σ at +53.7 s: 0.97MEASURED (polled /field) · σ at +54.7 s: 0.97MEASURED (polled /field) · σ at +56.0 s: 0.97MEASURED (polled /field) · σ at +57.1 s: 0.97MEASURED (polled /field) · σ at +58.2 s: 0.97MEASURED (polled /field) · σ at +59.2 s: 0.97MEASURED (polled /field) · σ at +60.3 s: 0.00MEASURED (polled /field) · σ at +61.4 s: 0.00MEASURED (polled /field) · σ at +62.4 s: 0.00MEASURED (polled /field) · σ at +63.5 s: 0.00MEASURED (polled /field) · σ at +64.6 s: 0.00MEASURED (polled /field) · σ at +65.6 s: 0.00MEASURED (polled /field) · σ at +66.7 s: 0.00MEASURED (polled /field) · σ at +67.7 s: 0.00MEASURED (polled /field) · σ at +68.8 s: 0.00MEASURED (polled /field) · σ at +69.9 s: 0.00MEASURED (polled /field) · σ at +71.0 s: 0.00MEASURED (polled /field) · σ at +72.0 s: 0.00MEASURED (polled /field) · σ at +73.1 s: 0.00MEASURED (polled /field) · σ at +74.1 s: 0.00MEASURED (polled /field) · σ at +75.2 s: 0.00MEASURED (polled /field) · σ at +76.3 s: 0.00MEASURED (polled /field) · σ at +77.3 s: 0.00MEASURED (polled /field) · σ at +78.4 s: 0.00MEASURED (polled /field) · σ at +79.5 s: 0.00MEASURED (polled /field) · σ at +80.6 s: 0.00MEASURED (polled /field) · σ at +81.7 s: 0.00MEASURED (polled /field) · σ at +82.8 s: 0.00MEASURED (polled /field) · σ at +83.9 s: 0.00MEASURED (polled /field) · σ at +85.0 s: 0.00MEASURED (polled /field) · σ at +86.0 s: 0.00MEASURED (polled /field) · σ at +87.1 s: 0.00MEASURED (polled /field) · σ at +88.2 s: 0.00MEASURED (polled /field) · σ at +89.2 s: 0.00MEASURED (polled /field) · σ at +90.3 s: 0.00MEASURED · σ in src/core at +0.0 s: 0.00MEASURED · σ in src/core at +5.6 s: 30.00MEASURED · σ in src/core at +19.9 s: 10.00MEASURED · σ in src/core at +27.2 s: 2.00MEASURED · σ in src/core at +34.0 s: 1.11MEASURED · σ in src/core at +36.0 s: 1.03MEASURED · σ in src/core at +40.0 s: 0.97
lane cadence (inhibition metric on the WebSocket)re-landing commits
024680+10+20+30+40+50+60+70+80+90seconds after the landing (dots: re-landing commits of the reworked proposals)lane cadence (s)lane cadence before the cascade: 1 sMEASURED · lane delay at +5.6 s: 8.00 s (inhibition ×8.00)MEASURED · lane delay at +10.4 s: 8.00 s (inhibition ×8.00)MEASURED · lane delay at +19.9 s: 8.00 s (inhibition ×8.00)MEASURED · lane delay at +27.2 s: 4.00 s (inhibition ×4.00)MEASURED · lane delay at +30.2 s: 4.00 s (inhibition ×4.00)MEASURED · lane delay at +34.0 s: 1.24 s (inhibition ×1.24)MEASURED · lane delay at +36.0 s: 1.07 s (inhibition ×1.07)MEASURED · lane delay at +38.0 s: 1.07 s (inhibition ×1.07)MEASURED · lane delay at +40.0 s: 1.00 s (inhibition ×1.00)re-landing commit at +10.4 s: 2 reworked proposalsre-landing commit at +19.9 s: 12 reworked proposalsre-landing commit at +27.1 s: 12 reworked proposalsre-landing commit at +30.2 s: 2 reworked proposalsre-landing commit at +34.0 s: 2 reworked proposals

Tables

Live runs (MEASURED, laptop-side latencies; serial writer on production, group commit and scale fixes on previews)

agentstrunk writerlanded/mincommits/minbatchttl p50 sttl p99 stake p50 mstake p99 mspropose p50 mspropose p99 msadmission waitsreturnedfailed / calls
10serial92.492.41.004.16.1354688115324000 / 868
10group commit215.6211.61.020.88.04741,514117425000 / 732
50serial84.484.41.0124.744.34873,402123498000 / 1,302
200serial125.971.81.4754.3108.81,0867,1411276484900 / 4,192
200group commit690.4589.91.222.99.35,98527,469220840233022 / 7,429
1,000serial138.563.71.9961.6127.97143,61715552421,439160 / 29,307
1,000group commit515.1369.21.414.810.415,03327,8231,3274,1642,8210816 / 9,927 (stopped early)
1,000group commit + scale fixes2923.6473.15.4513.020.95805,25119195410,75100 / 31,308
2,000group commit + scale fixes2713.9450.95.2414.823.05701,97920480723,60700 / 45,034
5,000group commit + scale fixes2777.7468.05.3012.527.26533,9602552,05430,651078 / 50,368

Simulator check against the live runs

agentstrunk writermeasured/minsimulated/minerrorttl p50 measured sttl p50 sim sbatch measuredbatch sim
10serial writer92.485.7-7%4.14.31.001.00
50serial writer84.486.4+2%24.728.31.011.00
200serial writer125.9138.0+10%54.355.21.471.72
1,000serial writer138.5144.9+5%61.658.21.991.80
10group commit215.6212.9-1%0.81.41.9 / cycle3.12
200group commit690.4680.8-1%2.911.418.6 / cycle45.60
1,000group commit515.1712.0+38%4.828.916.6 / cycle85.71

hono workload (SIMULATED, mean of seeds)

agentsmodellanded/minbatchrework %conflicts/1kttl p50 sttl p99 smsgs/landedmsgs/agent action
10Baseline6.61.000.131.02.281.66
10FireTrident, serial writer6.61.000.470.814.332472.16
10FireTrident + group commit6.61.000.470.814.332271.74
100Baseline56.21.005.77214.3142121.37
100FireTrident, serial writer62.11.0012.3751.420429456.36
100FireTrident + group commit62.01.2112.7771.021229560.45
1,000Baseline51.91.0021.73184771,0182231.02
1,000FireTrident, serial writer85.61.0242.53972709741,3917.37
1,000FireTrident + group commit204.52.9145.33191.66516707.51
10,000Baseline51.91.0021.73184771,0183,4251.00
10,000FireTrident, serial writer85.81.0241.43862709365,0221.33
10,000FireTrident + group commit205.62.9346.93331.66552,1451.35
100,000Baseline51.91.0021.73154751,02135,4191.00
100,000FireTrident, serial writer85.81.0241.938927196540,6831.03
100,000FireTrident + group commit207.22.9545.73221.563617,1311.03

Sensitivity: checks take 30 s (SIMULATED, hono workload)

FireTrident agents run checks in their own workspace before proposing, so the checks run in parallel. The baseline also re-runs them in the queue after every rebase, so they run serially.

agentsmodellanded/minttl p50 srework %
10Baseline1.9152.80.0
10FireTrident4.90.80.0
100Baseline1.9700.10.0
100FireTrident47.21.010.1
1,000Baseline1.9675.90.4
1,000FireTrident86.1274.541.0
10,000Baseline1.9675.90.4
10,000FireTrident85.7269.942.9
100,000Baseline1.9708.20.0
100,000FireTrident85.7269.042.4

Trunk writer cost per batch (MEASURED: k proposals in one region, landing time after the first proposal)

kcommits: size @ time
22 @ 1.12 s
108 @ 1.51 s, 2 @ 3.97 s
2524 @ 3.16 s, 1 @ 4.19 s
5049 @ 4.42 s, 1 @ 6.10 s

Method and assumptions

What changed in RegionDO for the demo

Findings and open issues

Reproduce

# live runs talk to a deployment: FT_URL and FT_TOKEN (its admin token) come from the environment or ~/.config/firetrident/env
node packages/bench/src/workload.ts --repo /tmp/ft-w2/hono --tree <checkout of hono HEAD> --out packages/bench/data/hono-workload.json
FT_URL=<your deployment> FT_TOKEN=<admin token> node packages/bench/src/live.ts --colony bench-w2-load --agents 200 --duration 90 --out results/live-n200.json
FT_URL=<your deployment> FT_TOKEN=<admin token> node packages/bench/src/scenarios/batchcost.ts --colony bench-w2-load --sizes 2,10,25,50 --out results/batchcost.json
FT_URL=<your deployment> FT_TOKEN=<admin token> node packages/bench/src/scenarios/cascade.ts --colony bench-w2-cascade --readers 30 --out results/cascade.json
node packages/bench/src/sim/sweep.ts --mode live --agents 10,50,200,1000 --seeds 1,2,3 --out results/sim-live.json
node packages/bench/src/sim/sweep.ts --mode history --agents 10,100,1000,10000,100000 --seeds 1,2,3 --duration 1200 --warmup 300 --out results/sim-history.json
node packages/bench/src/sim/sweep.ts --mode history --agents 10,100,1000,10000,100000 --test-ms 30000 --out results/sim-history-test30s.json
# group commit: same driver, intents topped up so the supply never runs out
FT_URL=<your deployment> FT_TOKEN=<admin token> node packages/bench/src/live.ts --colony g1-bench --agents 200 --duration 90 --intents 3000 --out results/2026-10-12-g1/live-n200.json
# scale: synthetic agents on a colony with review off (POST /api/colonies/<colony>/decide/policy {"enabled":false}) and a pre-forked pool
FT_URL=<your deployment> FT_TOKEN=<admin token> node packages/bench/src/live.ts --colony <colony> --agents 5000 --duration 120 --out results/2026-10-12-scale/live-n5000.json
node packages/bench/src/report.ts packages/bench/results/2026-10-12 packages/bench/results/2026-10-12-g1 packages/bench/results/2026-10-12-scale

Data: live-n*.json, sim-live.json, sim-history.json, sim-history-test30s.json, cascade.json, batchcost.json, results.json next to this page; ../2026-10-12-g1/ (group commit); ../2026-10-12-scale/ (scale runs, notes-check.json, summary.json). The production runs behind the README's results (Hono, a new project from a spec, an external agent over MCP, the vaccination meter) are in ../2026-10-12-prod/. Code: packages/bench. Generated 2026-10-12T20:57:41.536Z.