Internals: benchmark reports
Gateway API core additions: unused-feature regression check, 2026-10-15
Machine, pinning and method as in 2026-10-14-xeon-ingress-core-regression.md: 2× Xeon
E5-2650 v2, performance governor, turbo off. Server on CPUs 0-3 (4 workers), upstream
and applications on 4-7, oha 1.16.0 on 8-15 and 24-31, 64 connections. Daytime run.
The machine was about 8 % slower in absolute terms than on 2026-10-14 (base respond
109 684 against 126 651 req/s), so only the ratios inside this report are meaningful.
Commits: base = 273c67e (main before the Gateway API additions), new = 660ed05
(listener-scoped applications, **. suffix wildcard domains, fixed-status shares in
weighted backends, route precedence tie-break). scoped = the new binary started through
bench/scoped-wrapper.sh, which gives every application listeners: [http, https]: the
same routing, but through the per-listener host routers and the listener-name lookup per
request. All are plain release builds (cargo build --release --locked -p scalwsd --features http3, thin LTO, no PGO or BOLT); new and scoped are the same binary.
Configuration: bench/configs/scalws.yaml unchanged for base and new (no listeners,
no **. domain, no fixed-status share). For scoped the wrapper inserted
listeners: [http, https] into the four applications (list items at indentation 6 in that
file, as the script expects). bench/multi.sh, MODE=release (10 s warm-up, 30 s
measurement, 5 runs, variant order rotating), medians. Every measurement answered 2xx only;
no run was excluded.
Gate: new / base at least 0.98 and scoped / new at least 0.98 per scenario.
| scenario | base req/s | new req/s | scoped req/s | new / base | scoped / new | cpu_us base / new / scoped | gate |
|---|---|---|---|---|---|---|---|
| static-small | 68 708 | 67 971 | 67 747 | 0.989 | 0.997 | 58.20 / 58.83 / 59.03 | pass |
| respond | 109 684 | 108 695 | 107 691 | 0.991 | 0.991 | 36.45 / 36.79 / 37.13 | pass |
| proxy | 45 296 | 44 973 | 44 681 | 0.993 | 0.994 | 88.31 / 88.92 / 89.51 | pass |
| cache-hit | 85 246 | 83 373 | 83 559 | 0.978 | 1.002 | 46.91 / 47.97 / 47.86 | borderline |
cache-hit new / base was 0.978, so it was repeated alone (same method, 5 more runs,
xeon-gateway-ab-cache): base 85 316, new 84 522, scoped 84 742; new / base 0.991,
scoped / new 1.003; cpu_us 46.87 / 47.31 / 47.19. Across the two cache-hit runs the
new / base ratio is 0.978 and 0.991, and the 2026-10-14 report saw the same kind of
spread (0.984, 0.980, 0.991) for this scenario on an unchanged hot path.
Spread of the five runs (req/s, min to max, CV): static-small base 68 462-69 077 (0.4 %), new 66 704-68 859 (1.3 %), scoped 67 407-68 331 (0.5 %); respond base 109 077-110 296 (0.5 %), new 106 096-110 709 (1.8 %), scoped 106 464-107 807 (0.5 %); proxy base 44 033-45 653 (1.4 %), new 44 852-45 163 (0.3 %), scoped 44 460-45 375 (0.8 %); cache-hit base 84 865-85 624 (0.4 %), new 82 510-84 506 (1.2 %), scoped 82 439-84 087 (0.8 %).
p99 latency (ms), base / new / scoped: static-small 1.29 / 1.30 / 1.14; respond 0.73 / 0.75 / 0.73; proxy 2.25 / 2.39 / 2.44; cache-hit 1.05 / 1.04 / 0.96.
Peak resident memory (MiB), base / new / scoped: static-small 44 / 44 / 43; respond 44 / 43 / 43; proxy 49 / 48 / 48; cache-hit 49 / 48 / 48.
Verdict
The gate holds for every scenario. The listener-name lookup of the scoped path costs
0.0 % to 0.9 % of throughput (respond, the most sensitive scenario, 0.991 and about 0.9 %
more CPU per request), so the index-in-ConnInfo alternative is not needed. No profile
was taken since the gate holds on the repeat.
The benchmark configuration has an expired test certificate (bench.test), which the
server logs as an error at start; the plain-HTTP scenarios measured here are not affected,
and all three variants share it.
Results, in the bench host’s results directory: results/xeon-gateway-ab and
results/xeon-gateway-ab-cache (aggregate.csv, aggregate.txt,
run-N); binaries /opt/scalws-gw-base, /opt/scalws-gw-new,
/opt/scalws-gw-scoped.