Internals: benchmark reports
Upstream pools and route matching: prefix-only regression check, 2026-10-14
Machine and pinning as in 2026-10-10-xeon-bare-metal-pgo.md: 2× Xeon E5-2650 v2 (Ivy
Bridge EP, no AVX2), Ubuntu 26.04, kernel 7.0, performance governor, turbo off. Server
on CPUs 0-3 (four physical cores of socket 0, 4 workers), upstream and applications on
4-7, oha 1.16.0 on all of socket 1 (8-15, 24-31), 64 connections.
Commits: base = d61a50f (before Kubernetes phase 2a), new = 2384720 (upstream pools,
route matching and route policies). Both are plain release builds of the same profile
(cargo build --release --locked -p scalwsd --features http3, thin LTO, one codegen unit,
no PGO or BOLT, no target-specific CPU features); the shipped bench/configs/scalws.yaml
enables an HTTP/3 listener, so both need the http3 feature. The numbers are therefore
lower than those of the PGO + BOLT builds in run 7 and are only comparable with each
other.
Configuration under test: bench/configs/scalws.yaml unchanged, which has prefix routes
only (/api to a single-address proxy, /respond), so new takes the prefix fast path
and the existing ProxyHandler. bench/multi.sh with VARIANTS="base=... new=...",
MODE=release: 10 s warm-up, 30 s measurement, 5 runs, the order of the two variants
rotating from run to run; medians. Every measurement answered 2xx only; no run was
excluded.
Gate: new requests per second at least 0.98× base and server CPU per request at most
1.02× base, per scenario.
| scenario | base req/s | new req/s | new / base | cpu_us base | cpu_us new | cpu new / base | gate |
|---|---|---|---|---|---|---|---|
| static-small | 75 641 | 74 787 | 0.989 | 52.87 | 53.47 | 1.011 | pass |
| respond | 125 460 | 127 674 | 1.018 | 31.87 | 31.32 | 0.983 | pass |
| proxy | 51 601 | 51 055 | 0.989 | 77.50 | 78.33 | 1.011 | pass |
| cache-hit | 93 195 | 94 490 | 1.014 | 42.90 | 42.32 | 0.986 | pass |
Spread of the five runs (req/s, min to max, CV): static-small base 75 170-77 079 (0.9 %), new 73 403-76 166 (1.6 %); respond base 124 536-128 275 (1.2 %), new 122 535-128 870 (2.5 %); proxy base 51 422-51 842 (0.3 %), new 50 227-51 442 (1.1 %); cache-hit base 92 142-94 571 (1.0 %), new 91 842-96 017 (2.0 %). The differences of static-small and proxy (about 1 %) are inside the spread of the runs, and respond and cache-hit moved the other way by a similar amount.
p99 latency (ms), base / new: static-small 1.07 / 1.07; respond 0.67 / 0.65; proxy 2.04 / 2.23; cache-hit 0.92 / 0.89.
Peak resident memory of the server (MiB), base / new: static-small 44 / 43; respond
43 / 43; proxy 45 / 51; cache-hit 45 / 51. The value is the peak since the server
started (the four scenarios run against one process in this order), so proxy and
cache-hit include what the earlier scenarios left allocated. new peaked higher from the
proxy scenario on in every run (proxy: 46-51 MiB against 44-45 MiB); the cause is not
investigated here and it does not show up in CPU per request. The proxy p99 (+9 %) moved with the
throughput spread of the runs; the median latency is unchanged.
Verdict
The gate holds on all four scenarios: no throughput drop above 2 % and no CPU per request increase above 2 %. The prefix-only configuration costs the same with upstream pools, route matching and route policies in the binary as before.
Results, in the bench host’s results directory: results/xeon-pools-ab (aggregate.csv, aggregate.txt,
run-1 … run-5); binaries /opt/scalws-pools-base/scalwsd and
/opt/scalws-pools-new/scalwsd.