Benchmarks
2026-10-06 — Per-core loops, open file cache, kTLS, slimmer request path
Same harness, host and caveats as the other reports (Docker Desktop / WSL2, Ryzen 7
7800X3D, server on CPUs 0-3, applications 4-5, oha on 6-11, 64 connections, 10 s;
±15–20 % run-to-run). Both servers configured alike: open file cache with a check per
hit (OPEN_FILE_CACHE=check), kernel TLS on (KTLS=1, tls module loaded).
Final comparison (one run; two nginx rows replaced by repeats, see below)
scenario scb nginx caddy scb/nginx before (scb/nginx)
static-small 99.8k 121.9k 32.4k 0.82× 0.61–0.71×
static-1m 21.4k 23.7k 13.9k 0.90× 0.42×
respond 151.9k 242.4k 54.9k 0.63× 0.48×
proxy 68.1k 85.9k 25.6k 0.79× 0.66×
cache-hit 127.4k 93.6k 25.2k 1.36× 1.2×
tls-h2-static-small 86.7k 73.7k 23.3k 1.18× 0.64×
tls-static-1m (h1) 5.0–6.0k 6.1k 2.4k 0.82–0.98× (new; 1.34× without kTLS)
php 15.2–18.6k 20.6–21.7k 7.8k 0.75–0.87× 0.93–1.0×
node 20.3k 22.6k 25.2k 0.90× ≈1×
python 11.3k 10.7k 13.3k 1.05× ≈1×Peak RSS: scb 38–53 MiB (mimalloc, four runtimes), nginx 59–76 MiB, Caddy 47–61 MiB.
In the single run nginx showed 3.6k on tls-static-1m (23 CPU-s of 40) and 7.2k on php
(7.9 CPU-s); two repeats of those scenarios gave 6.1k/6.1k and 21.7k/20.6k, which are
used above. respond varies most between runs (nginx 177–268k, scb 117–167k).
What changed and what each step measured
| Step | Measurement |
|---|---|
| Open file cache (ADR-0028) | small files 72.2k → 79.4k; trusting entries for 60 s gained nothing more for scb (nginx +46 %) |
| Per-core event loops (ADR-0029) | respond 97.9k → 116k; minimal config 72k → 157k (= four separate processes) |
| Cache stage: hit-for-pass, sharded coalescing map, pre-resolved counters | respond with cache enabled 117k → 142k |
| Direct hyper builders instead of hyper-util auto | bare-hyper probe: auto layer −14 %; in scb 22.2 → 21.6 µs/request |
| Per-loop FastCGI and upstream pools | php 12.3–13.3k → 15.9–18.0k |
| mimalloc | proxy +17 %, cache-hit +26 % (two-run averages), +20 MiB RSS |
| kTLS (ADR-0030) | HTTPS/1.1 1 MiB 3.9k → 6.2k (nginx 6.1k with kTLS) |
Where the remaining gap is
- Per-request CPU on
respond: scb ≈ 21–23 µs, nginx ≈ 14–15 µs; split by DSO the kernel part is 15.6 vs 10.7 µs and user space 9.2 vs 3.4 µs. - A bare hyper server on the same per-core loops reaches 238–254k (≈ nginx); a raw
httparseserver 289k. The remaining ~6 µs are scb’s own layers (routing, context, metrics, body wrappers), spread over many small items — no single hotspot. - Applications behind scb (PHP, Node) lost a little with per-core loops; per-loop pools recovered most of PHP. Single-loop measurements show the WSL loopback leaving one loop ~30 % idle, so part of this may be environmental; a bare-metal run is still open.