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.

scenarioscalws finalfinal-hypernginx 1.28nginx 1.31OpenLiteSpeed 1.9.3final / nginx 1.31final / OLS
static-small111 956105 96694 27399 47794 9361.131.18
static-1m11 02410 99311 12911 12310 1770.991.08
respond206 933191 256200 648217 758—0.95—
proxy99 26581 63779 72992 52967 4351.071.47
cache-hit173 288158 76481 75286 30946 4912.013.73
tls-h2-static-small93 37295 93166 63968 25464 3111.371.45
php39 29841 76336 29337 18123 9751.061.64
node10 83310 89110 87910 82711 9541.000.91
python5 9576 3396 3356 3675 8830.941.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):

scenarioscalws finalfinal-hypernginx 1.28nginx 1.31OpenLiteSpeed
static-small4040808038
proxy4044848339
cache-hit4040818139
tls-h2-static-small4951999845

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-1m rose 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×).
  • respond 0.95× nginx 1.31 (0.90× in the evening run); still behind 1.31, ahead of 1.28.
  • php final 39 298 (CV 6.2 %) vs 41 761; final-hyper 41 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: final 0.94× nginx 1.31, while final-hyper matches 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-small p99 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].