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 25,913 4.13 0 0 0 55.1 25,045-26,219 3.54-4.77
fastapi_json skirr 24,972 4.15 0 0 0 38.0 24,655-25,723 4.01-4.68
fastapi_json skirr-before 24,607 5.23 0 0 0 38.0 24,194-24,938 5.06-5.39
Sampled server CPU clocks (MHz; median per-run mean, full observed range):
peregrine 4496; 4187-4700
skirr 4515; 4200-4700
skirr-before 4526; 4179-4700
Optimized Skirr change versus same-session saved baseline:
fastapi_json +1.5%; versus Peregrine -3.6%
Raw artifact: bench/results/fastapi-round3-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 25,997 14.25 0 0 0 56.3 25,274-26,446 12.90-16.99
fastapi_json skirr 24,962 16.03 0 0 0 38.1 24,712-25,152 15.44-17.44
fastapi_json skirr-before 24,730 16.33 0 0 0 38.1 24,032-24,803 15.46-17.22
Sampled server CPU clocks (MHz; median per-run mean, full observed range):
peregrine 4381; 398-4700
skirr 4441; 400-4700
skirr-before 4422; 400-4700
Optimized Skirr change versus same-session saved baseline:
fastapi_json +0.9%; versus Peregrine -4.0%
Raw artifact: bench/results/fastapi-round3-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
get_64k peregrine 73,523 1.64 0 0 0 32.7 72,847-73,924 1.54-1.69
get_64k skirr 84,124 1.44 0 0 0 17.1 82,845-84,302 1.38-2.48
get_64k skirr-before 84,006 1.53 0 0 0 17.1 84,002-84,397 1.50-1.55
post_4k peregrine 166,776 1.44 0 0 0 33.5 163,033-167,248 0.99-1.65
post_4k skirr 170,313 1.03 0 0 0 17.2 168,357-170,405 0.64-1.65
post_4k skirr-before 161,472 1.38 0 0 0 17.2 160,251-163,362 0.88-1.41
raw_get peregrine 207,913 1.21 0 0 0 32.7 202,505-208,346 0.83-1.56
raw_get skirr 221,271 0.74 0 0 0 17.1 214,622-222,484 0.42-1.95
raw_get skirr-before 214,414 0.93 0 0 0 17.2 212,993-214,583 0.60-1.53
Sampled server CPU clocks (MHz; median per-run mean, full observed range):
peregrine 4442; 4200-4700
skirr 4502; 4200-4701
skirr-before 4477; 4200-4700
Optimized Skirr change versus same-session saved baseline:
get_64k +0.1%; versus Peregrine +14.4%
post_4k +5.5%; versus Peregrine +2.1%
raw_get +3.2%; versus Peregrine +6.4%
Streaming: app waits 50ms after the first chunk; 20 sequential samples.
skirr first-byte 0.372ms; total 50.515ms
peregrine first-byte 0.455ms; total 50.759ms
skirr-before first-byte 0.444ms; total 50.678ms
Raw artifact: bench/results/fastapi-round3-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
get_64k peregrine 71,315 6.26 0 0 0 34.9 70,103-72,012 6.20-6.78
get_64k skirr 80,735 5.95 0 0 0 17.2 80,379-81,079 5.15-6.33
get_64k skirr-before 79,694 6.32 0 0 0 17.2 79,171-80,218 5.19-6.35
post_4k peregrine 158,854 2.84 0 0 0 38.7 158,372-159,288 2.65-3.00
post_4k skirr 162,714 2.55 0 0 0 18.1 162,046-163,526 2.28-2.71
post_4k skirr-before 160,500 2.77 0 0 0 18.1 155,495-163,462 2.31-3.23
raw_get peregrine 207,013 2.25 0 0 0 33.8 205,337-208,601 2.21-2.45
raw_get skirr 212,972 3.08 0 0 0 17.2 205,560-217,713 2.95-3.62
raw_get skirr-before 213,686 2.10 0 0 0 17.2 210,282-214,456 1.86-2.89
Sampled server CPU clocks (MHz; median per-run mean, full observed range):
peregrine 4263; 398-4700
skirr 4394; 399-4700
skirr-before 4301; 400-4700
Optimized Skirr change versus same-session saved baseline:
get_64k +1.3%; versus Peregrine +13.2%
post_4k +1.4%; versus Peregrine +2.4%
raw_get -0.3%; versus Peregrine +2.9%
Streaming: app waits 50ms after the first chunk; 20 sequential samples.
skirr first-byte 0.518ms; total 50.708ms
peregrine first-byte 0.325ms; total 50.565ms
skirr-before first-byte 0.507ms; total 50.592ms
Raw artifact: bench/results/fastapi-round3-controls-c256/results.json
Total completed requests across these comparisons: 47,395,587
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