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.
Medians of three five-second runs, each preceded by one-second warmup.
CPU governor/energy settings unchanged; shared laptop with dynamic clocks.
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 counter includes completed responses outside the 3s histogram.
These measurements do not establish production readiness or general superiority.
Connections: 64
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 >3s HTTP errors PSS MiB RPS range
fastapi_json peregrine 9,691 10.29 0 0 0 55.4 9,490-9,782
fastapi_json skirr 8,409 12.02 0 0 0 38.5 8,357-8,533
fastapi_json weft 8,815 11.81 0 0 0 39.8 8,715-9,062
get_64k peregrine 27,799 4.56 0 0 0 32.9 25,729-28,283
get_64k skirr 20,709 5.46 0 0 0 21.5 20,537-21,930
get_64k weft 24,768 4.65 0 0 0 22.7 23,398-24,911
post_4k peregrine 60,854 2.32 0 0 0 33.6 59,310-61,336
post_4k skirr 43,467 3.04 0 0 0 18.1 42,239-43,498
post_4k weft 48,956 3.01 0 0 0 19.9 48,945-50,299
raw_get peregrine 76,500 1.92 0 0 0 32.9 74,154-76,507
raw_get skirr 51,854 3.75 0 0 0 18.1 51,771-53,372
raw_get weft 61,361 2.34 0 0 0 18.4 60,496-62,056
Streaming: app waits 50ms after the first chunk; 20 sequential samples.
skirr first-byte 1.105ms; total 51.420ms
peregrine first-byte 1.164ms; total 51.384ms
weft first-byte 1.246ms; total 52.571ms
Raw artifact: bench/results/final-c64/results.json
Connections: 256
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 >3s HTTP errors PSS MiB RPS range
fastapi_json peregrine 9,706 38.47 0 0 0 56.5 9,634-9,713
fastapi_json skirr 8,442 41.97 0 0 0 39.1 8,226-8,487
fastapi_json weft 9,030 40.85 0 0 0 42.7 8,977-9,139
get_64k peregrine 25,973 15.87 0 0 0 34.0 25,379-26,548
get_64k skirr 18,640 24.77 0 0 0 34.2 18,449-18,986
get_64k weft 23,276 18.46 0 0 0 40.0 22,961-23,710
post_4k peregrine 63,920 7.14 0 0 0 38.9 61,373-64,589
post_4k skirr 39,668 10.75 0 0 0 20.4 39,545-40,370
post_4k weft 49,828 8.52 0 0 0 28.2 49,771-50,076
raw_get peregrine 77,540 6.24 0 0 0 34.0 77,460-78,220
raw_get skirr 50,962 8.53 0 0 0 20.4 50,849-51,311
raw_get weft 65,407 6.77 0 0 0 23.2 64,802-65,959
Streaming: app waits 50ms after the first chunk; 20 sequential samples.
skirr first-byte 1.118ms; total 51.513ms
peregrine first-byte 1.424ms; total 51.665ms
weft first-byte 1.333ms; total 52.748ms
Raw artifact: bench/results/final-c256/results.json
Total completed requests across these comparisons: 13,404,653
wrk histogram counter behavior: https://github.com/wg/wrk/blob/4.1.0/src/wrk.c#L301-L325