Benchmark Results
Version: 4.0.1
Last updated: 2026-09-28 21:15 UTC
Averaged over: 5 CI run(s) per deadline
Server config: shard_count=4, batch_size=64
CI numbers, not a baseline. These come from a shared 2-vCPU runner. The same version's rows in
history.mdspan ~1.45x on RPS and ~2x on p99 with no code change between them, so a ~10% move here is noise, not signal. Compare like-for-like on one machine before drawing a conclusion — seeenvironments.mdfor which comparisons are valid.
Throughput — deadline comparison
| Scenario | RPS (1ms) | ±σ (1ms) | RPS (2ms) | ±σ (2ms) | d1ms/d2ms |
|---|---|---|---|---|---|
| single_thread_buffered | 12,720 | ±84 | 12,210 | ±192 | 1.04× |
| single_thread_sync | 3,356 | ±95 | 3,130 | ±383 | 1.07× |
| thundering_herd_8_threads | 12,159 | ±251 | 11,725 | ±320 | 1.04× |
| thundering_herd_32_threads | 37,009 | ±971 | 36,827 | ±485 | 1.00× |
| thundering_herd_64_threads | 51,334 | ±948 | 47,471 | ±9,543 | 1.08× |
| connection_churn | 7,000 | ±115 | 7,358 | ±190 | 0.95× |
| fire_and_forget_overload | 4,130 | ±210 | 4,044 | ±247 | 1.02× |
Latency — single thread, batch_deadline_ms=1
| Metric | Durable | Durable (batched) | Buffered |
|---|---|---|---|
| Min | 225 µs | 224 µs | 50 µs |
| Mean | 300 µs | 292 µs | 77 µs |
| σ | 151 µs | 124 µs | 18 µs |
| p50 | 279 µs | 279 µs | 76 µs |
| p75 | 297 µs | 295 µs | 84 µs |
| p95 | 373 µs | 345 µs | 96 µs |
| p99 | 698 µs | 482 µs | 106 µs |
| p99.9 | 2.7 ms | 2.5 ms | 208 µs |
| Max | 3.6 ms | 3.1 ms | 669 µs |
Latency — single thread, batch_deadline_ms=2
| Metric | Durable | Durable (batched) | Buffered |
|---|---|---|---|
| Min | 234 µs | 229 µs | 49 µs |
| Mean | 302 µs | 296 µs | 80 µs |
| σ | 151 µs | 127 µs | 15 µs |
| p50 | 284 µs | 283 µs | 80 µs |
| p75 | 302 µs | 297 µs | 87 µs |
| p95 | 364 µs | 348 µs | 96 µs |
| p99 | 566 µs | 493 µs | 108 µs |
| p99.9 | 3.0 ms | 2.7 ms | 211 µs |
| Max | 4.2 ms | 3.4 ms | 567 µs |
Saturation Ramp — Buffered tier
Server started with
max_connections = 48. Levels above 48 threads trigger connection-cap exhaustion; the server must survive every level.
| Threads | RPS (d1ms) | RPS (d2ms) | I/O drops | Status |
|---|---|---|---|---|
| 8 | 53,914 | 54,030 | 0 | ok |
| 16 | 71,325 | 72,541 | 0 | ok |
| 32 | 88,320 | 88,719 | 0 | ok |
| 48 | 95,203 | 95,065 | 0 | ok |
| 64 | 95,658 | 93,153 | 16 | SATURATED ← |
| 96 | 89,360 | 95,855 | 48 | SATURATED |
Saturation Ramp — Sync tier
Server started with
max_connections = 48. Uses Sync durability to stress the group-fsync path under escalating concurrency.
| Threads | RPS (d1ms) | RPS (d2ms) | I/O drops | Status |
|---|---|---|---|---|
| 8 | 13,434 | 13,446 | 0 | ok |
| 16 | 19,895 | 21,965 | 0 | ok |
| 32 | 36,734 | 37,962 | 0 | ok |
| 48 | 49,331 | 49,425 | 0 | ok |
| 64 | 49,253 | 49,387 | 16 | SATURATED ← |
| 96 | 48,769 | 49,528 | 48 | SATURATED |
Generated by deploy/avg_benchmarks.py