Process Log Pipeline Benchmark (2026-09-19)¶
This report records the first synchronous-versus-asynchronous process-log comparison required by the log system architecture. It reports the median of three trials. It is still a development-host measurement rather than a portable service-level guarantee.
Environment¶
- Commit:
4dbeb59e8726735c2ec8f55ef5ba86e74603fa3d - Candidate: the working tree on
feat/async-process-logging - OS: Linux 6.14.0-1015-nvidia, ARM64
- Logical CPUs: 20
- File descriptor limit: 500,000
- Rust: 1.97.1
- Build: release profile
- Workload: 32 keep-alive connections, 2-second warmup, 10-second measured window, local mock LLM backend with a 1 ms fixed response delay
- Throttled sink: 4,096 bytes per second
- Trials: 3 per variant and sink; the table reports their medians
The synchronous binary was built from the commit above in a detached worktree. The asynchronous binary was built from the working branch. Both used the same lockfile, release profile, profile JSON, mock backend, and load driver.
Results¶
| Sink | Variant | RPS | p95 | p99 | Errors | Error rate | Peak RSS |
|---|---|---|---|---|---|---|---|
| Fast | Synchronous | 9,663.8 | 4.493 ms | 5.316 ms | 0 | 0% | 38.770 MiB |
| Fast | Asynchronous | 9,945.0 | 4.322 ms | 5.354 ms | 0 | 0% | 39.324 MiB |
| Throttled | Synchronous | 16.0 | n/a | n/a | 160 | 100% | 19.090 MiB |
| Throttled | Asynchronous | 9,918.3 | 4.524 ms | 5.525 ms | 0 | 0% | 42.152 MiB |
| Stalled | Synchronous | 16.0 | n/a | n/a | 160 | 100% | 18.813 MiB |
| Stalled | Asynchronous | 9,825.4 | 4.539 ms | 5.638 ms | 0 | 0% | 42.797 MiB |
With a fast sink, the asynchronous candidate delivered 2.9% more requests per second and reduced p95 latency by 3.8% in this run. Under throttled and stalled sinks, every measured synchronous request failed after the process pipe filled, while the asynchronous candidate retained roughly 9,825–9,918 RPS with zero request failures. Latency percentiles for the failed synchronous cases are intentionally reported as unavailable rather than as zero.
The higher RSS shown for the successful asynchronous overload cases is not a like-for-like service-capacity comparison: the synchronous process stopped making request progress before reaching its normal steady-state allocation. The asynchronous queue itself remains capped at 8,192 records and 16 MiB of retained payload with the default configuration.
Rerun after configurable queue limits¶
After logging.queue_capacity and logging.queue_capacity_bytes were wired through the startup path, the same binaries, workload, sink rates, and three-trial median procedure were run again. The candidate used the default 8,192-record and 16 MiB settings.
| Sink | Variant | RPS | p95 | p99 | Errors | Error rate | Peak RSS |
|---|---|---|---|---|---|---|---|
| Fast | Synchronous | 9,889.8 | 4.224 ms | 5.342 ms | 0 | 0% | 39.180 MiB |
| Fast | Asynchronous | 9,514.4 | 4.558 ms | 5.470 ms | 0 | 0% | 38.969 MiB |
| Throttled | Synchronous | 16.0 | n/a | n/a | 160 | 100% | 19.563 MiB |
| Throttled | Asynchronous | 9,850.4 | 4.599 ms | 5.715 ms | 0 | 0% | 42.246 MiB |
| Stalled | Synchronous | 16.0 | n/a | n/a | 160 | 100% | 18.813 MiB |
| Stalled | Asynchronous | 9,809.5 | 4.554 ms | 5.610 ms | 0 | 0% | 42.695 MiB |
On the fast sink, the candidate was 3.8% lower in throughput and 7.9% higher in p95 latency than the synchronous baseline, within the 10% regression budget. Under throttled and stalled sinks it again completed with zero errors at 103.5% and 103.1% of its own fast-sink throughput, while every measured synchronous request failed. All comparison gates passed.
Initial regression budget¶
Until the scheduled runner accumulates a longer history, the review budget for this implementation is:
- the fast-sink median must not regress by more than 10% in either throughput or p95 latency against the synchronous baseline;
- throttled and stalled candidates must complete with zero request failures;
- throttled and stalled throughput must remain at least 80% of the candidate's own fast-sink throughput; and
- queue depth must never exceed 8,192 records, retained queue payload must never exceed 16 MiB, and an individual formatted record must never exceed 64 KiB.
These bounds deliberately leave room for shared-host variance while rejecting the failure mode this change exists to remove. Replace them with runner-specific thresholds after repeated scheduled measurements establish dispersion.
Reproduction¶
Build one binary from the synchronous baseline and one from the candidate, then run:
TRIALS=3 perf/compare-log-pipeline.sh \
/path/to/synchronous/continuum-router \
/path/to/asynchronous/continuum-router
The harness writes the six machine-readable result files and a generated Markdown comparison below perf/results/log-pipeline/. That directory is git-ignored because repeated local and scheduled measurements are runtime artifacts; this checked-in report records the reviewed reference run.