Benchmarks
2026-10-05 — Docker Desktop smoke benchmark (M1 slice)
Not a performance claim. Docker Desktop on Windows (WSL2 VM), host shared with ~25 other running containers, no CPU frequency pinning. Use only to compare servers within this run and to find gross problems.
Environment
date: 2026-10-05T13:49:58Z
kernel: Linux 6.18.33.1-microsoft-standard-WSL2 x86_64 GNU/Linux
cpu_model: AMD Ryzen 7 7800X3D 8-Core Processor
cpus_online: 16
memory: 15Gi
server_cpus: 0-3 (4 workers)
upstream_cpus: 4-5
load_cpus: 6-11
duration_s: 10 warmup_s: 3 connections: 64
scb-webd: scb-webd 0.1.0
nginx: nginx version: nginx/1.22.1
caddy: 2.6.2
oha: oha 1.16.0
virtualization: 0::/Command: docker run --rm --cpuset-cpus 0-11 -e DURATION=10 -v "$PWD/bench/results:/results" scb-bench
(64 connections, 3 s warm-up, 10 s measured; server CPUs 0-3, upstream 4-5, oha 6-11).
Results
cpu_s = server CPU seconds during the 10 s window (max 40 for 4 CPUs).
peak_rss_mib = peak resident memory of the server process tree.
server scenario rps p50_ms p95_ms p99_ms success_rate non_2xx cpu_s peak_rss_mib
scb static-small 20208 3.08 5.57 6.94 1 0 28.28 15
scb static-1m 2147 29.3 39.52 46.09 1 0 28.1 42
scb respond 94943 0.54 1.61 2.55 1 0 24.99 42
scb proxy 48380 1.23 2.21 3.13 1 0 30.79 42
scb tls-h2-static-small 17614 3.53 6.02 7.41 1 0 29.21 42
nginx static-small 85034 0.69 1.22 1.94 1 0 36.22 53
nginx static-1m 22601 2.55 5.13 7.5 1 0 36.12 53
nginx respond 244371 0.19 0.66 1.35 1 0 34.19 53
nginx proxy 84059 0.66 1.47 2.86 1 0 31.02 54
nginx tls-h2-static-small 78673 0.77 1.35 2.21 1 0 36.58 68
caddy static-small 30916 1.31 6.63 11.78 1 0 31.34 47
caddy static-1m 13717 3.16 14.04 21.78 1 0 31.35 47
caddy respond 58857 0.68 3.34 6.96 1 0 31.83 47
caddy proxy 26671 1.87 6.19 9.18 1 0 32.69 51
caddy tls-h2-static-small 23119 2.15 7.16 11.47 1 0 33.47 51Findings
- Static files are the main gap (scb ≈ 0.24× nginx for 13 B files, ≈ 0.1× for 1 MiB).
scb uses only ~28 of 40 available CPU-seconds, i.e. it is latency-bound rather than
CPU-bound. Hypothesis: every request does a
spawn_blockinground trip for resolve/open, andtokio::fs::Fileperforms one blocking-pool hop per 64 KiB read; nginx usessendfileand an open-file cache. To verify withperfbefore changing anything (handoff §14). Candidate fixes, in order: a bounded open-file / metadata cache keyed by canonical path, reading small files in one blocking call,sendfile/splicefor plain-TCP large files on Linux. - Pure overhead (
respond): scb ≈ 0.39× nginx. Per-request work worth profiling: two label-hash lookups intoprometheus-clientfamilies, request-id formatting, severalArc<str>allocations, response body boxing/wrapping layers. - Proxy: scb ≈ 0.58× nginx, ≈ 1.8× Caddy 2.6.
- TLS + HTTP/2 static inherits finding 1.
- Memory: scb peak RSS 42 MiB vs nginx 53–68 MiB vs Caddy 47–51 MiB under this load.
- During the first run, oha’s HTTP/2 requests with an explicit
Hostthat differed from:authoritywere answered400by both scb and nginx (RFC 9113 §8.3.1) — the harness now sends no explicit Host header.