Cameleeringsimoom

simoom / Benchmarks

Benchmarks · campaign 4 · measured 2026-11-12

simoom against 20 servers, use case by use case

The servers a team would otherwise pick, from hyper, axum and actix-web to nginx, Go, Netty and Kestrel, each measured on the same droplet as simoom, with the same load machines, in the same round. Every chart and ratio on this page is generated from the raw records. The losses are in the same charts as the wins.

1.5xStatus endpoint, 256 clients: simoom against the median of 18 servers, range 0.94–12x; ahead of 16; behind may-minihttp
1.5xCPU per request at 50,000 req/s: simoom against the median of 18 servers, range 1.17–3.5x; ahead of 18
20xMemory per idle connection, 10,000 open: simoom against the median of 18 servers, range 0.94–49x; ahead of 17; behind nginx
6.4xStart-up to first answer: simoom against the median of 20 servers, range 1.57–762x; ahead of 20

simoom against the field, use case by use case

Campaign 4: simoom and 20 other servers, each measured on the same DigitalOcean droplet as simoom, with the same load machines, in the same round; three rounds on three droplets. Every bar is relative to simoom on that droplet, so no comparison mixes machines. Losses are in the same charts as wins.

Health checks and status endpoints

A small GET answered from memory: load-balancer probes, status pages, the busiest route of most APIs.

Behind may-minihttp: 6% more than simoom Status endpoint, 256 clients: requests/s with 99% within 1 ms; ahead of 16 of 18, level with 1; behind may-minihttp

JSON APIs

A 1 KB JSON body in, a 1 KB JSON body out, the shape of most service calls.

Behind may-minihttp: 5% more than simoom JSON API, 1 KB in and out, 256 clients: requests/s with 99% within 1 ms; ahead of 10 of 11; behind may-minihttp

HTTPS APIs and new TLS clients

The same API over TLS 1.3, and how many new and returning clients the handshake can take per second.

First of 8: simoom 30% more than the next best, axum + rustls HTTPS API, 256 clients: requests/s with 99% within 1 ms; ahead of 7 of 7

Clients that connect for every request

Serverless callers, scripts and devices that open a connection, send one request and close it.

Behind xitca-web: 29% more than simoom A new connection per request, 192 clients: requests/s with 99% within 5 ms; ahead of 12 of 18, level with 2; behind xitca-web, Cameleer's old server, actix-web, may-minihttp

Service-to-service HTTP/2

64 connections with 100 streams each, as gRPC and service meshes use HTTP/2.

Behind H2O: 11% more than simoom Service-to-service HTTP/2, 64 connections x 100 streams: requests/s with 99% within 5 ms; ahead of 9 of 11, level with 1; behind H2O

Mobile clients over HTTP/3

QUIC instead of TCP, for clients on lossy or changing networks.

Behind H2O: 43% more than simoom HTTP/3, 64 clients: requests/s with 99% within 1 ms; ahead of 2 of 3; behind H2O

Downloads

64 KB responses; 1 MB responses fill the network card for every server.

Level with the best, actix-web 64 KB downloads, 64 clients: requests/s with 99% within 5 ms; ahead of 0 of 7, level with 7

Many idle connections

Devices and push clients that stay connected and mostly say nothing.

Behind nginx: 6% less than simoom 10,000 idle connections: memory per connection; ahead of 17 of 18; behind nginx

Traffic spikes

195,000 requests per second offered, more than the network card can carry.

Behind actix-web: 22x more than simoom Traffic spike at 195,000 requests/s offered: answers within 1 ms per second; ahead of 9 of 18; behind actix-web, nginx, xitca-web, uWebSockets.js, Vert.x (Java), HAProxy, ntex, Netty (Java), fasthttp (Go)

Slow attackers

Real requests while 10,000 slowloris and 1,000 slow-read connections press.

Behind Go net/http: 44% lower than simoom Under 11,000 slow attackers: p99 of real requests; ahead of 10 of 18, level with 3; behind Go net/http, HAProxy, Vert.x (Java), Netty (Java), H2O

Start-up, size and memory

What a server costs before and while it answers.

First of 21: simoom 57% faster than the next best, hyper Start-up, process start to first answer: simoom's default build (HTTP/1.1, HTTP/2, WebSocket); ahead of 20 of 20

Health checks and status endpoints

A small GET answered from memory: load-balancer probes, status pages, the busiest route of most APIs.

Status endpoint, 64 clients: requests/s with 99% within 1 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, higher is better; in brackets, simoom in the same runs.

Vert.x (Java)104,411 req/s (simoom 69,415 req/s) · 50% more than simoom
fasthttp (Go)86,701 req/s (simoom 69,415 req/s) · 25% more than simoom
Netty (Java)83,229 req/s (simoom 69,415 req/s) · 20% more than simoom
may-minihttp158,598 req/s (simoom 137,443 req/s) · 15% more than simoom
uWebSockets.js78,369 req/s (simoom 69,415 req/s) · 13% more than simoom
simoom128,914 req/s
Cameleer's old server113,042 req/s (simoom 137,443 req/s) · simoom 22% more
nginx108,684 req/s (simoom 137,443 req/s) · simoom 26% more
actix-web99,838 req/s (simoom 128,914 req/s) · simoom 29% more
ntex98,846 req/s (simoom 128,914 req/s) · simoom 30% more
HAProxy103,791 req/s (simoom 137,443 req/s) · simoom 32% more
axum96,227 req/s (simoom 128,914 req/s) · simoom 34% more
hyper84,364 req/s (simoom 128,914 req/s) · simoom 53% more
xitca-web76,678 req/s (simoom 128,914 req/s) · simoom 68% more
Kestrel (.NET)38,276 req/s (simoom 69,415 req/s) · simoom 81% more
H2O70,543 req/s (simoom 137,443 req/s) · simoom 95% more
Go net/http31,854 req/s (simoom 69,415 req/s) · simoom 2.2x more
Envoy36,925 req/s (simoom 137,443 req/s) · simoom 3.7x more
Caddy18,937 req/s (simoom 137,443 req/s) · simoom 7.3x more

Status endpoint, 256 clients: requests/s with 99% within 1 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, higher is better; in brackets, simoom in the same runs.

may-minihttp154,590 req/s (simoom 145,171 req/s) · 6% more than simoom
simoom137,889 req/s
Vert.x (Java)100,036 req/s (simoom 102,713 req/s) · level
Netty (Java)96,967 req/s (simoom 102,713 req/s) · simoom 6% more
fasthttp (Go)95,444 req/s (simoom 102,713 req/s) · simoom 8% more
hyper110,931 req/s (simoom 137,889 req/s) · simoom 24% more
ntex108,326 req/s (simoom 137,890 req/s) · simoom 27% more
actix-web106,566 req/s (simoom 137,890 req/s) · simoom 29% more
axum101,477 req/s (simoom 137,890 req/s) · simoom 36% more
xitca-web92,021 req/s (simoom 137,890 req/s) · simoom 50% more
uWebSockets.js59,138 req/s (simoom 92,326 req/s) · simoom 56% more
HAProxy91,915 req/s (simoom 145,171 req/s) · simoom 58% more
nginx57,179 req/s (simoom 145,082 req/s) · simoom 2.5x more
Kestrel (.NET)36,871 req/s (simoom 102,713 req/s) · simoom 2.8x more
H2O40,551 req/s (simoom 145,082 req/s) · simoom 3.6x more
Go net/http24,600 req/s (simoom 92,326 req/s) · simoom 3.8x more
Envoy24,900 req/s (simoom 145,171 req/s) · simoom 5.8x more
Caddy12,546 req/s (simoom 145,082 req/s) · simoom 12x more
Cameleer's old server0 req/s (simoom 145,082 req/s) · only simoom met the target

Status endpoint, 1,024 clients: requests/s with 99% within 1 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, higher is better; in brackets, simoom in the same runs.

may-minihttp155,048 req/s (simoom 133,243 req/s) · 16% more than simoom
simoom133,243 req/s
nginx111,554 req/s (simoom 133,243 req/s) · simoom 19% more
HAProxy106,530 req/s (simoom 133,243 req/s) · simoom 25% more
Cameleer's old server103,814 req/s (simoom 133,243 req/s) · simoom 28% more
hyper102,154 req/s (simoom 153,049 req/s) · simoom 50% more
uWebSockets.js63,776 req/s (simoom 95,611 req/s) · simoom 50% more
fasthttp (Go)57,512 req/s (simoom 95,611 req/s) · simoom 66% more
Vert.x (Java)56,886 req/s (simoom 95,611 req/s) · simoom 68% more
Netty (Java)54,326 req/s (simoom 95,611 req/s) · simoom 76% more
actix-web83,023 req/s (simoom 153,049 req/s) · simoom 84% more
H2O67,646 req/s (simoom 133,243 req/s) · simoom 2.0x more
axum76,953 req/s (simoom 153,049 req/s) · simoom 2.0x more
ntex75,739 req/s (simoom 153,049 req/s) · simoom 2.0x more
xitca-web65,436 req/s (simoom 153,049 req/s) · simoom 2.3x more
Kestrel (.NET)30,702 req/s (simoom 95,611 req/s) · simoom 3.1x more
Envoy31,869 req/s (simoom 133,243 req/s) · simoom 4.2x more
Go net/http19,118 req/s (simoom 95,611 req/s) · simoom 5.0x more
Caddy12,587 req/s (simoom 133,243 req/s) · simoom 11x more

Latency at a fixed 50,000 requests/s (256 clients): p99

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, lower is better; in brackets, simoom in the same runs.

simoom355 µs
Vert.x (Java)391 µs (simoom 384 µs) · level
xitca-web405 µs (simoom 387 µs) · simoom 4% lower
actix-web410 µs (simoom 387 µs) · simoom 6% lower
ntex416 µs (simoom 387 µs) · simoom 7% lower
hyper418 µs (simoom 387 µs) · simoom 7% lower
may-minihttp400 µs (simoom 356 µs) · simoom 11% lower
axum404 µs (simoom 346 µs) · simoom 14% lower
fasthttp (Go)431 µs (simoom 366 µs) · simoom 15% lower
uWebSockets.js442 µs (simoom 366 µs) · simoom 17% lower
HAProxy441 µs (simoom 356 µs) · simoom 19% lower
Netty (Java)480 µs (simoom 366 µs) · simoom 24% lower
Cameleer's old server608 µs (simoom 356 µs) · simoom 41% lower
nginx839 µs (simoom 356 µs) · simoom 2.4x lower
H2O1,451 µs (simoom 355 µs) · simoom 4.1x lower
Kestrel (.NET)1,629 µs (simoom 384 µs) · simoom 4.2x lower
Go net/http3,140 µs (simoom 384 µs) · simoom 8.2x lower
Caddy1,519,387 µs (simoom 355 µs) · simoom 4282x lower
Envoy2,102,395 µs (simoom 355 µs) · simoom 5926x lower

CPU per request at a fixed 50,000 requests/s

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, lower is better; in brackets, simoom in the same runs.

simoom23.6 µs
may-minihttp28.6 µs (simoom 24.3 µs) · simoom 15% lower
Vert.x (Java)30.4 µs (simoom 24.5 µs) · simoom 19% lower
actix-web31.2 µs (simoom 24.1 µs) · simoom 23% lower
ntex32.1 µs (simoom 24.1 µs) · simoom 25% lower
xitca-web32.4 µs (simoom 24.1 µs) · simoom 26% lower
nginx32.9 µs (simoom 24.3 µs) · simoom 26% lower
hyper32.6 µs (simoom 24.1 µs) · simoom 26% lower
uWebSockets.js34.2 µs (simoom 24.5 µs) · simoom 28% lower
Netty (Java)34.6 µs (simoom 24.5 µs) · simoom 29% lower
Cameleer's old server36.2 µs (simoom 24.3 µs) · simoom 33% lower
HAProxy36.6 µs (simoom 24.3 µs) · simoom 34% lower
axum35.6 µs (simoom 23.6 µs) · simoom 34% lower
fasthttp (Go)33.2 µs (simoom 21.3 µs) · simoom 36% lower
H2O47.0 µs (simoom 24.3 µs) · simoom 48% lower
Go net/http53.0 µs (simoom 23.7 µs) · simoom 2.2x lower
Kestrel (.NET)64.1 µs (simoom 23.7 µs) · simoom 2.7x lower
Envoy68.4 µs (simoom 21.1 µs) · simoom 3.2x lower
Caddy86.3 µs (simoom 24.3 µs) · simoom 3.5x lower

JSON APIs

A 1 KB JSON body in, a 1 KB JSON body out, the shape of most service calls.

JSON API, 1 KB in and out, 256 clients: requests/s with 99% within 1 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, higher is better; in brackets, simoom in the same runs.

may-minihttp124,126 req/s (simoom 118,427 req/s) · 5% more than simoom
simoom118,427 req/s
ntex83,326 req/s (simoom 95,678 req/s) · simoom 15% more
hyper71,171 req/s (simoom 84,755 req/s) · simoom 19% more
Netty (Java)109,736 req/s (simoom 135,188 req/s) · simoom 23% more
fasthttp (Go)86,456 req/s (simoom 109,366 req/s) · simoom 26% more
axum127,598 req/s (simoom 161,438 req/s) · simoom 27% more
Vert.x (Java)101,178 req/s (simoom 135,188 req/s) · simoom 34% more
actix-web54,349 req/s (simoom 84,755 req/s) · simoom 56% more
uWebSockets.js57,141 req/s (simoom 109,366 req/s) · simoom 91% more
Kestrel (.NET)22,515 req/s (simoom 109,366 req/s) · simoom 4.9x more
Go net/http20,755 req/s (simoom 109,366 req/s) · simoom 5.3x more

HTTPS APIs and new TLS clients

The same API over TLS 1.3, and how many new and returning clients the handshake can take per second.

HTTPS API, 256 clients: requests/s with 99% within 1 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, higher is better; in brackets, simoom in the same runs.

simoom134,004 req/s
axum + rustls103,343 req/s (simoom 134,004 req/s) · simoom 30% more
H2O79,386 req/s (simoom 103,311 req/s) · simoom 30% more
HAProxy61,431 req/s (simoom 103,311 req/s) · simoom 68% more
nginx40,777 req/s (simoom 103,311 req/s) · simoom 2.5x more
Go net/http28,755 req/s (simoom 167,300 req/s) · simoom 5.8x more
Caddy11,843 req/s (simoom 103,311 req/s) · simoom 8.7x more
Cameleer's old server0 req/s (simoom 103,311 req/s) · only simoom met the target

New TLS 1.3 clients: full handshakes per second

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, higher is better; in brackets, simoom in the same runs.

axum + rustls11,633/s (simoom 9,396/s) · 24% more than simoom
simoom9,431/s
H2O6,464/s (simoom 8,973/s) · simoom 39% more
Go net/http5,247/s (simoom 9,410/s) · simoom 79% more
Caddy4,928/s (simoom 8,973/s) · simoom 82% more
nginx3,695/s (simoom 8,973/s) · simoom 2.4x more
HAProxy3,483/s (simoom 8,973/s) · simoom 2.6x more
Cameleer's old server1,517/s (simoom 8,973/s) · simoom 5.9x more

Returning TLS 1.3 clients: resumed handshakes per second

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, higher is better; in brackets, simoom in the same runs.

axum + rustls13,537/s (simoom 12,388/s) · 9% more than simoom
simoom10,565/s
H2O6,351/s (simoom 9,924/s) · simoom 56% more
Caddy5,163/s (simoom 9,924/s) · simoom 92% more
Go net/http6,555/s (simoom 12,717/s) · simoom 94% more
Cameleer's old server4,487/s (simoom 9,924/s) · simoom 2.2x more
nginx4,216/s (simoom 9,924/s) · simoom 2.4x more
HAProxy4,004/s (simoom 9,924/s) · simoom 2.5x more

Clients that connect for every request

Serverless callers, scripts and devices that open a connection, send one request and close it.

A new connection per request, 192 clients: requests/s with 99% within 5 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, higher is better; in brackets, simoom in the same runs.

xitca-web21,149 req/s (simoom 16,359 req/s) · 29% more than simoom
Cameleer's old server15,961 req/s (simoom 14,684 req/s) · 9% more than simoom
actix-web17,137 req/s (simoom 16,359 req/s) · 5% more than simoom
may-minihttp23,052 req/s (simoom 22,116 req/s) · 4% more than simoom
nginx22,618 req/s (simoom 22,116 req/s) · level
hyper16,378 req/s (simoom 16,359 req/s) · level
simoom17,323 req/s
ntex15,388 req/s (simoom 16,359 req/s) · simoom 6% more
axum15,009 req/s (simoom 16,359 req/s) · simoom 9% more
uWebSockets.js15,887 req/s (simoom 17,323 req/s) · simoom 9% more
HAProxy19,946 req/s (simoom 22,116 req/s) · simoom 11% more
Go net/http15,226 req/s (simoom 17,323 req/s) · simoom 14% more
H2O18,847 req/s (simoom 22,116 req/s) · simoom 17% more
Vert.x (Java)13,747 req/s (simoom 17,323 req/s) · simoom 26% more
Caddy17,055 req/s (simoom 22,116 req/s) · simoom 30% more
fasthttp (Go)23,317 req/s (simoom 30,488 req/s) · simoom 31% more
Netty (Java)12,852 req/s (simoom 17,323 req/s) · simoom 35% more
Kestrel (.NET)12,206 req/s (simoom 17,323 req/s) · simoom 42% more
Envoy10,848 req/s (simoom 22,116 req/s) · simoom 2.0x more

Service-to-service HTTP/2

64 connections with 100 streams each, as gRPC and service meshes use HTTP/2.

Service-to-service HTTP/2, 64 connections x 100 streams: requests/s with 99% within 5 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, higher is better; in brackets, simoom in the same runs.

H2O168,962 req/s (simoom 152,445 req/s) · 11% more than simoom
HAProxy154,298 req/s (simoom 152,445 req/s) · level
simoom153,230 req/s
hyper143,530 req/s (simoom 153,232 req/s) · simoom 7% more
axum124,765 req/s (simoom 153,232 req/s) · simoom 23% more
Vert.x (Java)102,563 req/s (simoom 153,230 req/s) · simoom 49% more
nginx87,443 req/s (simoom 152,445 req/s) · simoom 74% more
Kestrel (.NET)82,084 req/s (simoom 153,230 req/s) · simoom 87% more
actix-web72,914 req/s (simoom 153,232 req/s) · simoom 2.1x more
Envoy48,266 req/s (simoom 152,445 req/s) · simoom 3.2x more
Go net/http35,588 req/s (simoom 153,230 req/s) · simoom 4.3x more
Caddy14,206 req/s (simoom 152,445 req/s) · simoom 11x more

Mobile clients over HTTP/3

QUIC instead of TCP, for clients on lossy or changing networks.

HTTP/3, 64 clients: requests/s with 99% within 1 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, higher is better; in brackets, simoom in the same runs.

H2O74,961 req/s (simoom 52,259 req/s) · 43% more than simoom
simoom75,916 req/s
quinn + h342,518 req/s (simoom 70,001 req/s) · simoom 65% more
Caddy3,370 req/s (simoom 52,259 req/s) · simoom 16x more

Downloads

64 KB responses; 1 MB responses fill the network card for every server.

64 KB downloads, 64 clients: requests/s with 99% within 5 ms

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, higher is better; in brackets, simoom in the same runs.

actix-web3,780 req/s (simoom 3,773 req/s) · level
axum3,779 req/s (simoom 3,773 req/s) · level
hyper3,776 req/s (simoom 3,773 req/s) · level
simoom3,773 req/s
Go net/http3,771 req/s (simoom 3,772 req/s) · level
nginx3,780 req/s (simoom 3,786 req/s) · level
Caddy3,779 req/s (simoom 3,786 req/s) · level
H2O3,773 req/s (simoom 3,786 req/s) · level

Many idle connections

Devices and push clients that stay connected and mostly say nothing.

10,000 idle connections: memory per connection

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, lower is better; in brackets, simoom in the same runs.

nginx538 B (simoom 575 B) · 6% less than simoom
simoom573 B
uWebSockets.js1,038 B (simoom 570 B) · simoom 45% less
H2O1,681 B (simoom 575 B) · simoom 2.9x less
HAProxy1,682 B (simoom 575 B) · simoom 2.9x less
Cameleer's old server3,363 B (simoom 575 B) · simoom 5.8x less
Netty (Java)7,207 B (simoom 570 B) · simoom 13x less
xitca-web7,412 B (simoom 573 B) · simoom 13x less
Vert.x (Java)9,772 B (simoom 570 B) · simoom 17x less
Kestrel (.NET)10,564 B (simoom 570 B) · simoom 19x less
actix-web11,892 B (simoom 573 B) · simoom 21x less
fasthttp (Go)16,581 B (simoom 570 B) · simoom 29x less
Envoy17,544 B (simoom 575 B) · simoom 31x less
hyper17,790 B (simoom 573 B) · simoom 31x less
ntex18,674 B (simoom 573 B) · simoom 33x less
may-minihttp20,293 B (simoom 575 B) · simoom 35x less
Go net/http21,714 B (simoom 570 B) · simoom 38x less
axum21,888 B (simoom 573 B) · simoom 38x less
Caddy28,449 B (simoom 575 B) · simoom 49x less

100,000 idle connections: memory per connection

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, lower is better; in brackets, simoom in the same runs.

nginx528 B (simoom 532 B) · level
simoom532 B
HAProxy1,311 B (simoom 532 B) · simoom 2.5x less
H2O1,680 B (simoom 532 B) · simoom 3.2x less
Netty (Java)4,598 B (simoom 531 B) · simoom 8.7x less
Vert.x (Java)6,839 B (simoom 531 B) · simoom 13x less
Kestrel (.NET)10,162 B (simoom 531 B) · simoom 19x less
actix-web10,649 B (simoom 535 B) · simoom 20x less
hyper16,293 B (simoom 535 B) · simoom 30x less
fasthttp (Go)16,312 B (simoom 531 B) · simoom 31x less
Envoy17,303 B (simoom 532 B) · simoom 33x less
axum20,356 B (simoom 535 B) · simoom 38x less
Go net/http20,398 B (simoom 531 B) · simoom 38x less
may-minihttp21,035 B (simoom 532 B) · simoom 40x less
Caddy36,864 B (simoom 532 B) · simoom 69x less

Traffic spikes

195,000 requests per second offered, more than the network card can carry.

Traffic spike at 195,000 requests/s offered: answers within 1 ms per second

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, higher is better; in brackets, simoom in the same runs.

actix-web59,015 req/s (simoom 2,743 req/s) · 22x more than simoom
nginx29,135 req/s (simoom 6,264 req/s) · 4.7x more than simoom
xitca-web8,887 req/s (simoom 2,743 req/s) · 3.2x more than simoom
uWebSockets.js4,796 req/s (simoom 3,309 req/s) · 45% more than simoom
Vert.x (Java)4,724 req/s (simoom 3,309 req/s) · 43% more than simoom
HAProxy8,462 req/s (simoom 6,264 req/s) · 35% more than simoom
ntex3,524 req/s (simoom 2,743 req/s) · 28% more than simoom
Netty (Java)4,078 req/s (simoom 3,309 req/s) · 23% more than simoom
fasthttp (Go)4,053 req/s (simoom 3,309 req/s) · 22% more than simoom
simoom3,309 req/s
hyper2,179 req/s (simoom 2,743 req/s) · simoom 26% more
may-minihttp4,811 req/s (simoom 6,264 req/s) · simoom 30% more
Cameleer's old server3,724 req/s (simoom 6,264 req/s) · simoom 68% more
axum956 req/s (simoom 2,743 req/s) · simoom 2.9x more
H2O231 req/s (simoom 6,264 req/s) · simoom 27x more
Envoy0 req/s (simoom 6,264 req/s) · only simoom met the target
Caddy0 req/s (simoom 6,264 req/s) · only simoom met the target
Go net/http0 req/s (simoom 3,309 req/s) · only simoom met the target
Kestrel (.NET)0 req/s (simoom 3,309 req/s) · only simoom met the target

Traffic spike: all answers per second

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, higher is better; in brackets, simoom in the same runs.

uWebSockets.js159,633 req/s (simoom 150,344 req/s) · 6% more than simoom
Vert.x (Java)159,263 req/s (simoom 150,344 req/s) · 6% more than simoom
fasthttp (Go)155,502 req/s (simoom 150,344 req/s) · 3% more than simoom
axum160,356 req/s (simoom 155,270 req/s) · 3% more than simoom
xitca-web159,705 req/s (simoom 155,270 req/s) · level
Netty (Java)153,384 req/s (simoom 150,344 req/s) · level
actix-web157,873 req/s (simoom 155,270 req/s) · level
hyper157,030 req/s (simoom 155,270 req/s) · level
Kestrel (.NET)151,455 req/s (simoom 150,344 req/s) · level
ntex155,665 req/s (simoom 155,270 req/s) · level
Cameleer's old server160,264 req/s (simoom 159,868 req/s) · level
nginx160,028 req/s (simoom 159,868 req/s) · level
HAProxy160,007 req/s (simoom 159,868 req/s) · level
simoom155,270 req/s
may-minihttp159,107 req/s (simoom 159,868 req/s) · level
Go net/http77,379 req/s (simoom 150,344 req/s) · simoom 94% more
H2O65,179 req/s (simoom 159,868 req/s) · simoom 2.5x more
Envoy54,944 req/s (simoom 159,868 req/s) · simoom 2.9x more
Caddy37,083 req/s (simoom 159,868 req/s) · simoom 4.3x more

Slow attackers

Real requests while 10,000 slowloris and 1,000 slow-read connections press.

Under 11,000 slow attackers: p99 of real requests

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, lower is better; in brackets, simoom in the same runs.

Go net/http445 µs (simoom 791 µs) · 44% lower than simoom
HAProxy375 µs (simoom 568 µs) · 34% lower than simoom
Vert.x (Java)578 µs (simoom 791 µs) · 27% lower than simoom
Netty (Java)632 µs (simoom 791 µs) · 20% lower than simoom
H2O462 µs (simoom 568 µs) · 19% lower than simoom
Caddy561 µs (simoom 568 µs) · level
simoom791 µs
fasthttp (Go)799 µs (simoom 791 µs) · level
hyper1,026 µs (simoom 1,002 µs) · level
axum1,065 µs (simoom 1,002 µs) · simoom 6% lower
may-minihttp1,073 µs (simoom 568 µs) · simoom 47% lower
nginx1,146 µs (simoom 568 µs) · simoom 2.0x lower
uWebSockets.js2,171 µs (simoom 791 µs) · simoom 2.7x lower
actix-web4,428 µs (simoom 1,002 µs) · simoom 4.4x lower
xitca-web6,844 µs (simoom 1,002 µs) · simoom 6.8x lower
Envoy4,147 µs (simoom 568 µs) · simoom 7.3x lower
ntex17,285 µs (simoom 1,002 µs) · simoom 17x lower
Kestrel (.NET)159,777 µs (simoom 791 µs) · simoom 202x lower
Cameleer's old server31,708,938 µs (simoom 568 µs) · simoom 55845x lower

Start-up, size and memory

What a server costs before and while it answers.

Start-up, process start to first answer: simoom's default build (HTTP/1.1, HTTP/2, WebSocket)

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, lower is better; in brackets, simoom in the same runs.

simoom0.94 ms
simoom, smallest build0.98 ms (simoom 0.97 ms) · level
hyper1.48 ms (simoom 0.94 ms) · simoom 57% faster
axum1.56 ms (simoom 0.94 ms) · simoom 66% faster
actix-web1.81 ms (simoom 0.94 ms) · simoom 93% faster
Cameleer's old server1.74 ms (simoom 0.90 ms) · simoom 93% faster
axum + rustls1.91 ms (simoom 0.94 ms) · simoom 2.0x faster
quinn + h31.96 ms (simoom 0.94 ms) · simoom 2.1x faster
ntex2.07 ms (simoom 0.94 ms) · simoom 2.2x faster
fasthttp (Go)3.04 ms (simoom 0.97 ms) · simoom 3.1x faster
xitca-web3.29 ms (simoom 0.94 ms) · simoom 3.5x faster
Go net/http3.74 ms (simoom 0.97 ms) · simoom 3.9x faster
may-minihttp8.03 ms (simoom 0.90 ms) · simoom 8.9x faster
H2O14.34 ms (simoom 0.90 ms) · simoom 16x faster
nginx19.57 ms (simoom 0.90 ms) · simoom 22x faster
Caddy33.32 ms (simoom 0.90 ms) · simoom 37x faster
Envoy72.84 ms (simoom 0.90 ms) · simoom 81x faster
uWebSockets.js112.58 ms (simoom 0.97 ms) · simoom 116x faster
HAProxy200.42 ms (simoom 0.90 ms) · simoom 223x faster
Kestrel (.NET)366.56 ms (simoom 0.95 ms) · simoom 386x faster
Netty (Java)467.01 ms (simoom 0.95 ms) · simoom 492x faster
Vert.x (Java)723.57 ms (simoom 0.95 ms) · simoom 762x faster

Start-up, process start to first answer: simoom's full server (also TLS 1.3 and HTTP/3)

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, lower is better; in brackets, simoom in the same runs.

simoom, smallest build0.98 ms (simoom 1.73 ms) · 77% faster than simoom
simoom1.49 ms
hyper1.48 ms (simoom 1.46 ms) · level
axum1.56 ms (simoom 1.46 ms) · simoom 7% faster
actix-web1.81 ms (simoom 1.46 ms) · simoom 24% faster
axum + rustls1.91 ms (simoom 1.46 ms) · simoom 31% faster
quinn + h31.96 ms (simoom 1.46 ms) · simoom 34% faster
ntex2.07 ms (simoom 1.46 ms) · simoom 42% faster
Cameleer's old server1.74 ms (simoom 1.20 ms) · simoom 45% faster
fasthttp (Go)3.04 ms (simoom 1.73 ms) · simoom 76% faster
Go net/http3.74 ms (simoom 1.73 ms) · simoom 2.2x faster
xitca-web3.29 ms (simoom 1.46 ms) · simoom 2.3x faster
may-minihttp8.03 ms (simoom 1.20 ms) · simoom 6.7x faster
H2O14.34 ms (simoom 1.20 ms) · simoom 12x faster
nginx19.57 ms (simoom 1.20 ms) · simoom 16x faster
Caddy33.32 ms (simoom 1.20 ms) · simoom 28x faster
Envoy72.84 ms (simoom 1.20 ms) · simoom 61x faster
uWebSockets.js112.58 ms (simoom 1.73 ms) · simoom 65x faster
HAProxy200.42 ms (simoom 1.20 ms) · simoom 167x faster
Kestrel (.NET)366.56 ms (simoom 1.52 ms) · simoom 241x faster
Netty (Java)467.01 ms (simoom 1.52 ms) · simoom 307x faster
Vert.x (Java)723.57 ms (simoom 1.52 ms) · simoom 476x faster

Program size, stripped: simoom's default build (HTTP/1.1, HTTP/2, WebSocket)

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, lower is better; in brackets, simoom in the same runs.

may-minihttp515 KB (simoom 735 KB) · 30% smaller than simoom
simoom735 KB
simoom, smallest build743 KB (simoom 735 KB) · level
xitca-web1,025 KB (simoom 735 KB) · simoom 28% smaller
nginx1,283 KB (simoom 735 KB) · simoom 43% smaller
Cameleer's old server1,307 KB (simoom 735 KB) · simoom 44% smaller
H2O1,499 KB (simoom 735 KB) · simoom 2.0x smaller
ntex1,831 KB (simoom 735 KB) · simoom 2.5x smaller
hyper2,069 KB (simoom 735 KB) · simoom 2.8x smaller
axum2,246 KB (simoom 735 KB) · simoom 3.1x smaller
actix-web2,450 KB (simoom 735 KB) · simoom 3.3x smaller
HAProxy3,765 KB (simoom 735 KB) · simoom 5.1x smaller
axum + rustls5,400 KB (simoom 735 KB) · simoom 7.3x smaller
fasthttp (Go)5,739 KB (simoom 735 KB) · simoom 7.8x smaller
quinn + h35,766 KB (simoom 735 KB) · simoom 7.8x smaller
Go net/http6,180 KB (simoom 735 KB) · simoom 8.4x smaller
Caddy48.5 MB (simoom 735 KB) · simoom 68x smaller
Envoy101.9 MB (simoom 735 KB) · simoom 142x smaller

Program size, stripped: simoom's full server (also TLS 1.3 and HTTP/3)

Bar: simoom = 100 on the same droplet, longer is better. Value: one round, lower is better; in brackets, simoom in the same runs.

may-minihttp515 KB (simoom 1,550 KB) · 3.0x smaller than simoom
simoom, smallest build743 KB (simoom 1,550 KB) · 2.1x smaller than simoom
xitca-web1,025 KB (simoom 1,550 KB) · 34% smaller than simoom
nginx1,283 KB (simoom 1,550 KB) · 17% smaller than simoom
Cameleer's old server1,307 KB (simoom 1,550 KB) · 16% smaller than simoom
H2O1,499 KB (simoom 1,550 KB) · 3% smaller than simoom
simoom1,550 KB
ntex1,831 KB (simoom 1,550 KB) · simoom 15% smaller
hyper2,069 KB (simoom 1,550 KB) · simoom 25% smaller
axum2,246 KB (simoom 1,550 KB) · simoom 31% smaller
actix-web2,450 KB (simoom 1,550 KB) · simoom 37% smaller
HAProxy3,765 KB (simoom 1,550 KB) · simoom 2.4x smaller
axum + rustls5,400 KB (simoom 1,550 KB) · simoom 3.5x smaller
fasthttp (Go)5,739 KB (simoom 1,550 KB) · simoom 3.7x smaller
quinn + h35,766 KB (simoom 1,550 KB) · simoom 3.7x smaller
Go net/http6,180 KB (simoom 1,550 KB) · simoom 4.0x smaller
Caddy48.5 MB (simoom 1,550 KB) · simoom 32x smaller
Envoy101.9 MB (simoom 1,550 KB) · simoom 67x smaller

Memory at rest (PSS)

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 3 rounds, lower is better; in brackets, simoom in the same runs.

simoom, smallest build901 KB (simoom 1,869 KB) · 2.1x less than simoom
Cameleer's old server1,142 KB (simoom 1,844 KB) · 38% less than simoom
hyper1,315 KB (simoom 1,769 KB) · 26% less than simoom
xitca-web1,349 KB (simoom 1,769 KB) · 24% less than simoom
axum1,466 KB (simoom 1,769 KB) · 17% less than simoom
simoom1,844 KB
actix-web1,885 KB (simoom 1,761 KB) · simoom 7% less
ntex2,069 KB (simoom 1,761 KB) · simoom 15% less
axum + rustls3,110 KB (simoom 1,769 KB) · simoom 43% less
quinn + h33,468 KB (simoom 1,769 KB) · simoom 2.0x less
H2O5,028 KB (simoom 1,844 KB) · simoom 2.7x less
fasthttp (Go)6,396 KB (simoom 1,869 KB) · simoom 3.4x less
Go net/http8,108 KB (simoom 1,869 KB) · simoom 4.3x less
may-minihttp9,152 KB (simoom 1,844 KB) · simoom 5.0x less
Caddy45.8 MB (simoom 1,873 KB) · simoom 25x less
Envoy62.1 MB (simoom 1,844 KB) · simoom 34x less
Kestrel (.NET)68.9 MB (simoom 1,869 KB) · simoom 38x less
nginx70.7 MB (simoom 1,844 KB) · simoom 39x less
Netty (Java)72.6 MB (simoom 1,869 KB) · simoom 40x less
uWebSockets.js79.4 MB (simoom 1,869 KB) · simoom 43x less
Vert.x (Java)94.3 MB (simoom 1,869 KB) · simoom 52x less
HAProxy139.5 MB (simoom 1,844 KB) · simoom 77x less

Peak memory while serving the status endpoint (PSS)

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 2 rounds, lower is better; in brackets, simoom in the same runs.

simoom, smallest build2,099 KB (simoom 3,010 KB) · 30% less than simoom
simoom2,864 KB
xitca-web4,279 KB (simoom 2,880 KB) · simoom 33% less
ntex5,352 KB (simoom 2,880 KB) · simoom 46% less
H2O6,203 KB (simoom 3,008 KB) · simoom 2.1x less
actix-web6,912 KB (simoom 2,880 KB) · simoom 2.4x less
fasthttp (Go)12.6 MB (simoom 3,010 KB) · simoom 4.3x less
axum14.9 MB (simoom 2,848 KB) · simoom 5.3x less
hyper16.1 MB (simoom 2,848 KB) · simoom 5.8x less
Go net/http20.4 MB (simoom 2,833 KB) · simoom 7.4x less
may-minihttp28.3 MB (simoom 3,008 KB) · simoom 9.6x less
Cameleer's old server68.8 MB (simoom 3,008 KB) · simoom 23x less
Caddy65.1 MB (simoom 2,840 KB) · simoom 23x less
nginx71.3 MB (simoom 3,008 KB) · simoom 24x less
Envoy69.8 MB (simoom 2,840 KB) · simoom 25x less
uWebSockets.js92.1 MB (simoom 3,010 KB) · simoom 31x less
Kestrel (.NET)122.6 MB (simoom 3,010 KB) · simoom 42x less
HAProxy143.1 MB (simoom 3,008 KB) · simoom 49x less
Netty (Java)437.3 MB (simoom 3,010 KB) · simoom 149x less
Vert.x (Java)441.7 MB (simoom 3,010 KB) · simoom 150x less

Peak memory while serving the JSON API (PSS)

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 2 rounds, lower is better; in brackets, simoom in the same runs.

simoom, smallest build2,209 KB (simoom 3,058 KB) · 28% less than simoom
simoom2,992 KB
ntex8,860 KB (simoom 2,988 KB) · simoom 3.0x less
actix-web10.9 MB (simoom 2,988 KB) · simoom 3.7x less
fasthttp (Go)13.3 MB (simoom 3,058 KB) · simoom 4.4x less
axum16.0 MB (simoom 2,988 KB) · simoom 5.5x less
hyper17.4 MB (simoom 2,988 KB) · simoom 6.0x less
Go net/http20.6 MB (simoom 3,058 KB) · simoom 6.9x less
may-minihttp29.2 MB (simoom 3,129 KB) · simoom 9.5x less
Kestrel (.NET)118.5 MB (simoom 3,058 KB) · simoom 40x less
uWebSockets.js121.8 MB (simoom 3,058 KB) · simoom 41x less
Vert.x (Java)458.1 MB (simoom 3,058 KB) · simoom 153x less
Netty (Java)454.6 MB (simoom 2,996 KB) · simoom 155x less

Peak memory while serving HTTPS (PSS)

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 2 rounds, lower is better; in brackets, simoom in the same runs.

simoom6,983 KB
H2O9,701 KB (simoom 8,089 KB) · simoom 17% less
axum + rustls16.4 MB (simoom 7,385 KB) · simoom 2.3x less
Go net/http25.9 MB (simoom 6,997 KB) · simoom 3.8x less
Cameleer's old server40.3 MB (simoom 8,089 KB) · simoom 5.1x less
Caddy70.3 MB (simoom 8,089 KB) · simoom 8.9x less
nginx86.2 MB (simoom 8,089 KB) · simoom 11x less
HAProxy164.9 MB (simoom 8,089 KB) · simoom 21x less

Peak memory while serving HTTP/3 (PSS)

Bar: simoom = 100 on the same droplet, longer is better. Value: median of 2 rounds, lower is better; in brackets, simoom in the same runs.

H2O23.7 MB (simoom 42.1 MB) · 44% less than simoom
simoom41.1 MB
quinn + h354.1 MB (simoom 41.5 MB) · simoom 23% less
Caddy98.2 MB (simoom 42.1 MB) · simoom 2.3x less

Every server, every measure

simoom's advantage on the same droplet, median of rounds: above 1.00 simoom is better, below 1.00 the other server is. Column names link to the charts above.

servers1-64s1-256s1-1024p99-50kcpu-50ks3s4-64ks5s7-tlss7-fulls7-resumeds8h3s9s9-totals10idle-10kidle-100kcold-plaincoldsize-plainsizebasepeak-s1peak-s3peak-s7peak-h3
actix-web1.291.291.841.061.301.561.000.95–––2.10–0.050.984.4220.7519.901.931.243.331.581.072.403.74––
axum1.341.361.991.171.511.271.001.09–––1.23–2.870.971.0638.2038.051.661.073.051.450.835.355.48––
axum + rustls––––––––1.300.810.92–––––––2.031.317.343.481.76––2.27–
Caddy7.2611.5610.594282.373.55–1.001.308.721.821.9210.7315.511000000.004.310.9949.4869.2937.0227.7767.6032.0625.0623.49–8.902.33
Cameleer's old server1.221000000.001.281.711.49––0.921000000.005.912.21––1.681.0055845.265.85–1.931.451.780.840.6223.41–5.10–
Envoy3.725.834.185925.583.24––2.04–––3.16–1000000.002.917.3030.5132.5280.9360.70141.9467.3234.4825.18–––
fasthttp (Go)0.801.081.661.181.561.26–1.31–––––0.820.971.0129.0930.723.131.767.813.703.424.294.44––
Go net/http2.183.755.008.172.245.271.001.145.821.791.944.31–1000000.001.940.5638.0938.413.862.168.413.994.347.396.893.79–
H2O1.953.581.974.091.93–1.001.171.301.391.560.900.7027.122.450.812.923.1615.9311.952.040.972.732.06–1.200.56
HAProxy1.321.581.251.241.50––1.111.682.582.480.99–0.741.000.662.932.46222.69167.025.122.4377.4948.73–20.88–
hyper1.531.241.501.081.351.191.001.00–––1.07–1.260.991.0231.0530.451.571.012.811.330.745.795.95––
Kestrel (.NET)1.812.793.114.242.714.86–1.42–––1.87–1000000.000.99201.9918.5319.14385.85241.16––37.7541.7139.70––
may-minihttp0.870.940.861.131.170.95–0.96–––––1.301.001.8935.2939.548.926.690.700.334.969.629.55––
Netty (Java)0.831.061.761.311.411.23–1.35–––––0.810.980.8012.648.66491.59307.24––39.77148.78155.39––
nginx1.262.541.192.361.35–1.000.982.532.432.351.74–0.211.002.020.940.9921.7416.311.750.8339.2824.26–10.91–
ntex1.301.272.021.081.331.15–1.06–––––0.781.0017.2432.59–2.201.422.491.181.171.862.97––
quinn + h3––––––––––––1.65–––––2.091.347.843.721.96–––1.30
uWebSockets.js0.891.561.501.211.401.91–1.09–––––0.690.942.741.82–116.0665.08––43.5031.3240.79––
Vert.x (Java)0.661.031.681.021.241.34–1.26–––1.49–0.700.940.7317.1412.88761.65476.03––51.67150.27153.41––
xitca-web1.681.502.341.051.35––0.77–––––0.310.976.8312.94–3.502.251.390.660.761.49–––

The data behind this section: c4.json, generated from the raw records in bench/results by bench/cloud/c4-report.py and scripts/c4-site.py.

Where simoom is behind

Every measure where another server beat simoom by more than 3% on the same droplet, generated from the same data as the charts.

  • Status endpoint, 64 clients: requests/s with 99% within 1 ms. Vert.x (Java) (50% more than simoom), fasthttp (Go) (25% more than simoom), Netty (Java) (20% more than simoom), may-minihttp (15% more than simoom), uWebSockets.js (13% more than simoom). Chart
  • Status endpoint, 256 clients: requests/s with 99% within 1 ms. may-minihttp (6% more than simoom). Chart
  • Status endpoint, 1,024 clients: requests/s with 99% within 1 ms. may-minihttp (16% more than simoom). Chart
  • JSON API, 1 KB in and out, 256 clients: requests/s with 99% within 1 ms. may-minihttp (5% more than simoom). Chart
  • A new connection per request, 192 clients: requests/s with 99% within 5 ms. xitca-web (29% more than simoom), Cameleer's old server (9% more than simoom), actix-web (5% more than simoom), may-minihttp (4% more than simoom). Chart
  • New TLS 1.3 clients: full handshakes per second. axum + rustls (24% more than simoom). Chart
  • Returning TLS 1.3 clients: resumed handshakes per second. axum + rustls (9% more than simoom). Chart
  • Service-to-service HTTP/2, 64 connections x 100 streams: requests/s with 99% within 5 ms. H2O (11% more than simoom). Chart
  • HTTP/3, 64 clients: requests/s with 99% within 1 ms. H2O (43% more than simoom). Chart
  • Traffic spike at 195,000 requests/s offered: answers within 1 ms per second. actix-web (22x more than simoom), nginx (4.7x more than simoom), xitca-web (3.2x more than simoom), uWebSockets.js (45% more than simoom), Vert.x (Java) (43% more than simoom), HAProxy (35% more than simoom), ntex (28% more than simoom), Netty (Java) (23% more than simoom), fasthttp (Go) (22% more than simoom). Chart
  • Traffic spike: all answers per second. uWebSockets.js (6% more than simoom), Vert.x (Java) (6% more than simoom), fasthttp (Go) (3% more than simoom), axum (3% more than simoom). Chart
  • Under 11,000 slow attackers: p99 of real requests. Go net/http (44% lower than simoom), HAProxy (34% lower than simoom), Vert.x (Java) (27% lower than simoom), Netty (Java) (20% lower than simoom), H2O (19% lower than simoom). Chart
  • 10,000 idle connections: memory per connection. nginx (6% less than simoom). Chart
  • Program size, stripped: simoom's default build (HTTP/1.1, HTTP/2, WebSocket). may-minihttp (30% smaller than simoom). Chart
  • Program size, stripped: simoom's full server (also TLS 1.3 and HTTP/3). may-minihttp (3.0x smaller than simoom), xitca-web (34% smaller than simoom), nginx (17% smaller than simoom), Cameleer's old server (16% smaller than simoom), H2O (3% smaller than simoom). Chart
  • Memory at rest (PSS). Cameleer's old server (38% less than simoom), hyper (26% less than simoom), xitca-web (24% less than simoom), axum (17% less than simoom). Chart
  • Peak memory while serving HTTP/3 (PSS). H2O (44% less than simoom). Chart
  • Coverage. Every figure comes from 4-vCPU droplets with a single-queue network card. Larger machines and multi-queue network cards have not been measured.

How it was measured

Machines and fairness

  • Server: DigitalOcean c-4 droplets, 4 dedicated vCPUs, Bangalore region, Ubuntu 24.04, a network card with one receive queue.
  • Three lanes: each with its own server droplet and two load droplets. simoom ran in every lane and every round, so every server is compared with simoom on the same droplet, with the same load machines, in the same round.
  • Rotation: the server droplets rotate between rounds, so each lane meets each droplet. The published ratio is the median of the per-round ratios.
  • Open loop: requests are sent at a fixed rate whatever the server does, so a slow server can't slow the load down and hide its own latency.

What is counted

  • Throughput: the highest steady rate at which 99% of answers arrive within 1 ms (5 ms for new connections, downloads and HTTP/2) with no errors. A run that stalls counts as a miss.
  • Rounds: round 1 ran every scenario for every server. Rounds 2 and 3 repeated the status endpoint at 256 clients, the JSON API, new connections, TLS and CPU on the other two droplets. Each chart says how many rounds it holds.
  • Builds: each server in its fastest documented configuration; the programs and their configuration are in bench/competitors.
  • simoom: the benchmark server with all features, commit a81c368. Its smallest build appears only in the footprint charts.

The review that led to this campaign: docs/benchmark-review.md. The analysis, with every anomaly: campaign 4 analysis. Raw records, scripts and programs: bench/results, bench/cloud.

Against the server it replaced

The Cameleering test that matters most: the original. simoom replaces Cameleer's thread-per-connection server (cameleer-http). Both return the same 13-byte answer on the same machine (WSL2).

Start-up and idle memory (2026-11-11)

buildto first answeridle memory
simoom, plain0.73 ms1,018 KB
cameleer-http, plain0.77 ms1,017 KB
simoom, TLS (P-256)0.87 ms1,360 KB
cameleer-http, TLS1.37 ms1,317 KB

10 alternating rounds; TLS memory after the fix of 2026-11-12 (issue K11).

Under load (2026-11-09)

measuresimoomcameleer-http
requests per second293k–311k172k–173k
p99 latency0.32–0.44 ms0.87–0.91 ms
CPU per requestabout 13 µsabout 23 µs
1,000 idle connections2.7 MB7.7 MB

Server on 4 CPUs, 64 connections, closed-loop load from 8 other CPUs.

The owner's requirement was start-up and memory within 5% of cameleer-http. Idle memory with TLS is 3.3% higher; everything else is level or better. This result is the simoom row of the Cameleering ledger.

What a build adds to your binary

Bytes added to examples/hello.rs over an empty fn main, stripped, x86-64 Linux, dist profile. The budgets are targets the build enforces: scripts/size.sh fails when one is exceeded.

buildsizebudget
HTTP/1.1 only214,568 B256,000 B
HTTP/1.1, HTTP/2, TLS, io_uring583,680 B614,400 B
everything: HTTP/1.1, HTTP/2, HTTP/3, TLS, WebSocket, io_uring935,064 B1,048,576 B

The HTTP/1.1 and full rows are from 2026-11-11, the TLS row from 2026-11-12.

Whole benchmark programs, simoom against every other server, are in the footprint charts above: start-up, size and memory.

Conformance and interop

checkresult
h2spec 2.6.0146/146, in 30 consecutive runs
QUIC Interop Runner, server role, against ngtcp2, quiche and quic-go54 of 58 supported pairs; the 4 failures are 0-RTT (refused by design) and ECN (not implemented)
HTTP Garden, next to nginx, Apache httpd, h2o, hyper, gunicorn and Go0 desyncs, 0 dangerous discrepancies
Request smuggling behind nginx 1.24 and haproxy 2.8165 streams, 0 desyncs; accepted 0 requests that both refused
testssl.sh 3.2.1no vulnerabilities found
Test suite777 tests on Windows, 791 on Linux, zero warnings

Versions, commands and details: Security. No independent security audit has been done yet.

Common questions

What is the fastest Rust HTTP server?

It depends on the use case. In campaign 4, with 10 Rust servers among the 21 on the same droplets, may-minihttp led plain requests per second by 5–16% and simoom was second; simoom led HTTPS throughput, CPU per request and start-up; actix-web kept the most answers within 1 ms during a traffic spike. Numbers from different machines should not be compared: droplets of the same type differed by up to 7x.

Why p99 under 1 ms instead of maximum requests per second?

A server that answers more requests but makes some of them wait seconds is not faster for the people waiting. The headline figure is the highest steady rate at which 99% of answers arrive within 1 ms, with the load sent at a fixed rate so a slow server cannot slow the load down and hide its latency.

Why are only servers on the same droplet compared?

Droplets of the same type differed by up to 7x for every server in earlier campaigns. A comparison across droplets would measure the machines, not the servers. In campaign 4 simoom ran in every lane and every round, so every server has a simoom run on its own droplet to be compared with.

Can I rerun the benchmarks?

Yes. The scripts are in bench/cloud in the repository, the competitor programs in bench/competitors, and the raw records, HDR logs and analyses in bench/results. bench/cloud/c4-report.py turns the records into the tables on this page, and scripts/size.sh reproduces the size table.

Has anyone else measured simoom?

Not yet. Every figure here was measured by the project. If you measure it differently and get a different number, open an issue with your method.