Benchmarks
Release-mode comparison after the run-6 security fixes — 2026-10-12
Machine and pinning as in 2026-10-10-xeon-bare-metal-pgo.md: 2× Xeon E5-2650 v2, server
on four physical cores (CPUs 0-3), upstream and applications on 4-7, oha on socket 1;
performance governor, turbo off, BIOS power profile at maximum performance (see
2026-10-11-xeon-release-nginx-openlitespeed.md). MODE=release: 10 s warm-up, 30 s measurement,
5 runs, medians. scalws: the PGO + BOLT build of tools/pgo-build.sh (ADR-0047, commit
2f0e5b5), the merge of the audit run-6 security fixes; final with both experimental
settings, final-hyper with defaults.
OpenLiteSpeed 1.9.3 (official release tarball, SHA-256 checked) with
bench/configs/openlitespeed; it has no fixed-response directive, so respond is not
measured for it. Every measurement of every server answered 2xx only. No run was excluded.
The clock log (socket-0 cores every 5 s) shows 2 593–2 600 MHz under load; 50 of 1 930
samples have a core below 2.4 GHz, isolated single samples.
| scenario | scalws final | final-hyper | nginx 1.28 | nginx 1.31 | OpenLiteSpeed 1.9.3 | final / nginx 1.31 | final / OLS |
|---|---|---|---|---|---|---|---|
| static-small | 111 956 | 105 966 | 94 273 | 99 477 | 94 936 | 1.13 | 1.18 |
| static-1m | 11 024 | 10 993 | 11 129 | 11 123 | 10 177 | 0.99 | 1.08 |
| respond | 206 933 | 191 256 | 200 648 | 217 758 | — | 0.95 | — |
| proxy | 99 265 | 81 637 | 79 729 | 92 529 | 67 435 | 1.07 | 1.47 |
| cache-hit | 173 288 | 158 764 | 81 752 | 86 309 | 46 491 | 2.01 | 3.73 |
| tls-h2-static-small | 93 372 | 95 931 | 66 639 | 68 254 | 64 311 | 1.37 | 1.45 |
| php | 39 298 | 41 763 | 36 293 | 37 181 | 23 975 | 1.06 | 1.64 |
| node | 10 833 | 10 891 | 10 879 | 10 827 | 11 954 | 1.00 | 0.91 |
| python | 5 957 | 6 339 | 6 335 | 6 367 | 5 883 | 0.94 | 1.01 |
Server CPU per request (µs, cpu_us): static-small 35.72 / nginx 1.31 40.2 / OLS 40.1;
proxy 40.23 / 43.17 / 55.63; respond 19.32 / 18.36 / —; php 59.97 / 77.73 / 108.0.
Versions: nginx 1.28.3 (Ubuntu 26.04 package) and 1.31.6 (built from the signed source
tarball); load: oha with 64 connections.
Peak resident memory of the server processes (MiB, median of 5 runs, peak_rss_mib):
| scenario | scalws final | final-hyper | nginx 1.28 | nginx 1.31 | OpenLiteSpeed |
|---|---|---|---|---|---|
| static-small | 40 | 40 | 80 | 80 | 38 |
| proxy | 40 | 44 | 84 | 83 | 39 |
| cache-hit | 40 | 40 | 81 | 81 | 39 |
| tls-h2-static-small | 49 | 51 | 99 | 98 | 45 |
p99 latency (ms), scalws final / nginx 1.31 / OLS: static-small 0.68 / 0.71 / 2.05; proxy 0.84 / 0.89 / 2.63; cache-hit 0.46 / 0.80 / 4.31; tls-h2-static-small 1.43 / 1.12 / 1.39; php 1.90 / 2.01 / 7.16.
Compared with 2026-10-11
- The security fixes cost no measurable throughput on the paths they touch: static-small 111 956 vs 109 315, proxy 99 265 vs 96 258 (evening re-measurement), cache-hit 173 288 vs 163 866 req/s; CPU per request is equal or lower (static-small 35.7 vs 36.6 µs, proxy 40.2 vs 41.5 µs).
static-1mrose for every server (~9.9k → ~11.0k req/s): the earlier run was at the lowered clock; it is now a tie with nginx (0.99×).respond0.95× nginx 1.31 (0.90× in the evening run); still behind 1.31, ahead of 1.28.phpfinal39 298 (CV 6.2 %) vs 41 761;final-hyper41 763 (CV 1.8 %). Both stay ahead of nginx (1.06× / 1.12×) and well ahead of OpenLiteSpeed.- RSS rose by 3–8 MiB for scalws (36 → 40 MiB static-small); still half of nginx.
Open points:
respond(0.95×) behind nginx 1.31.python:final0.94× nginx 1.31, whilefinal-hypermatches nginx (6 339 vs 6 367) with the same application CPU; the own HTTP/1 path costs 5 % here.node: OpenLiteSpeed 9 % ahead of both scalws and nginx.tls-h2-static-smallp99 1.43 ms vs nginx 1.12 ms, at 1.37× the throughput.
Results: xeon:[private host path] (aggregate.csv, aggregate.txt, run-1 …
run-5); clock log xeon:[private host path].