Skirr prototype: local HTTP/1 comparison
One worker pinned to CPU 0; wrk on CPUs 4-7; identical apps and Python.
Access logs, request IDs, compression, caches and lifespan disabled.
Server allocator/GC defaults retained; Skirr does not alter application GC policy.
Medians of repeated runs; counts, duration and warmup are recorded per matrix.
Temporary performance-profile hold for final matrices; CPU clocks sampled per run.
No TLS, HTTP/2, WebSockets or pipelining in the throughput workload.
Exact body/status checked before/after each run, not on every wrk response.
P99 below is median per-run wrk P99, not a pooled percentile.
Timeout semantics follow the recorded generator; all counters are retained.
These measurements do not establish production readiness or general superiority.
Connections: 64; repeats: 5; duration: 8s; warmup: 1s; offered rate: unlimited
Power profile: performance
Versions: {"fastapi": "0.143.1", "peregrine-server": "1.1.7", "uvloop": "0.23.0", "weft-server": "0.1.0"}
Workload Server Req/s P99 ms IO failures Timeouts HTTP errors PSS MiB RPS range P99 range ms
fastapi_json peregrine 26,145 3.71 0 0 0 55.1 26,059-26,466 3.52-3.92
fastapi_json skirr 25,340 3.76 0 0 0 38.0 25,151-25,569 3.60-4.13
fastapi_json skirr-before 25,475 3.68 0 0 0 38.0 25,196-25,629 3.53-4.14
Sampled server CPU clocks (MHz; median per-run mean, full observed range):
peregrine 4529; 400-4700
skirr 4569; 4200-4700
skirr-before 4565; 4200-4700
Optimized Skirr change versus same-session saved baseline:
fastapi_json -0.5%; versus Peregrine -3.1%
Raw artifact: bench/results/latency-round4-c64/results.json
Connections: 256; repeats: 5; duration: 8s; warmup: 1s; offered rate: unlimited
Power profile: performance
Versions: {"fastapi": "0.143.1", "peregrine-server": "1.1.7", "uvloop": "0.23.0", "weft-server": "0.1.0"}
Workload Server Req/s P99 ms IO failures Timeouts HTTP errors PSS MiB RPS range P99 range ms
fastapi_json peregrine 26,317 13.28 0 0 0 56.3 25,892-26,600 12.49-16.31
fastapi_json skirr 25,401 14.97 0 0 0 38.0 25,068-25,429 11.99-15.00
fastapi_json skirr-before 25,236 15.20 0 0 0 38.0 25,137-25,389 12.59-15.29
Sampled server CPU clocks (MHz; median per-run mean, full observed range):
peregrine 4437; 400-4700
skirr 4444; 400-4700
skirr-before 4497; 400-4700
Optimized Skirr change versus same-session saved baseline:
fastapi_json +0.7%; versus Peregrine -3.5%
Raw artifact: bench/results/latency-round4-c256/results.json
Connections: 64; repeats: 3; duration: 5s; warmup: 1s; offered rate: unlimited
Power profile: performance
Versions: {"fastapi": "0.143.1", "peregrine-server": "1.1.7", "uvloop": "0.23.0", "weft-server": "0.1.0"}
Workload Server Req/s P99 ms IO failures Timeouts HTTP errors PSS MiB RPS range P99 range ms
post_4k peregrine 169,376 0.86 0 0 0 33.5 164,869-170,093 0.74-2.35
post_4k skirr 173,349 0.61 0 0 0 17.2 172,359-174,894 0.60-0.99
post_4k skirr-before 171,826 0.61 0 0 0 17.2 171,196-171,836 0.57-0.69
raw_get peregrine 208,930 0.59 0 0 0 32.5 207,489-210,787 0.55-0.62
raw_get skirr 223,293 0.63 0 0 0 17.2 222,141-224,232 0.51-0.65
raw_get skirr-before 219,536 0.59 0 0 0 17.1 218,867-219,721 0.55-0.81
Sampled server CPU clocks (MHz; median per-run mean, full observed range):
peregrine 4495; 4200-4700
skirr 4525; 4264-4700
skirr-before 4478; 4200-4700
Optimized Skirr change versus same-session saved baseline:
post_4k +0.9%; versus Peregrine +2.3%
raw_get +1.7%; versus Peregrine +6.9%
Streaming: app waits 50ms after the first chunk; 20 sequential samples.
skirr first-byte 0.643ms; total 50.726ms
peregrine first-byte 0.654ms; total 50.816ms
skirr-before first-byte 0.619ms; total 50.800ms
Raw artifact: bench/results/latency-round4-controls-c64/results.json
Connections: 256; repeats: 3; duration: 5s; warmup: 1s; offered rate: unlimited
Power profile: performance
Versions: {"fastapi": "0.143.1", "peregrine-server": "1.1.7", "uvloop": "0.23.0", "weft-server": "0.1.0"}
Workload Server Req/s P99 ms IO failures Timeouts HTTP errors PSS MiB RPS range P99 range ms
post_4k peregrine 159,926 2.72 0 0 0 38.8 158,523-162,221 2.61-2.93
post_4k skirr 163,193 2.72 0 0 0 18.1 160,385-168,524 2.44-11.14
post_4k skirr-before 160,233 2.67 0 0 0 18.1 156,373-162,487 2.60-2.68
raw_get peregrine 208,492 2.23 0 0 0 33.9 207,903-210,360 1.94-2.33
raw_get skirr 228,182 2.06 0 0 0 18.1 228,137-229,612 1.91-2.29
raw_get skirr-before 217,799 1.74 0 0 0 17.2 217,548-219,441 1.70-1.92
Sampled server CPU clocks (MHz; median per-run mean, full observed range):
peregrine 4315; 399-4700
skirr 4370; 980-4686
skirr-before 4330; 401-4687
Optimized Skirr change versus same-session saved baseline:
post_4k +1.8%; versus Peregrine +2.0%
raw_get +4.8%; versus Peregrine +9.4%
Streaming: app waits 50ms after the first chunk; 20 sequential samples.
skirr first-byte 0.590ms; total 50.725ms
peregrine first-byte 0.620ms; total 50.681ms
skirr-before first-byte 0.638ms; total 50.810ms
Raw artifact: bench/results/latency-round4-controls-c256/results.json
Total completed requests across these comparisons: 41,177,246
wrk histogram counter behavior: https://github.com/wg/wrk/blob/4.1.0/src/wrk.c#L301-L325
wrk2 corrected fixed-rate histograms: https://github.com/giltene/wrk2/tree/44a94c17d8e6a0bac8559b53da76848e430cb7a7