nilo
Experimental · Zig · engine: nilo_http on zio · standard configuration · completeness 4/4
A toolkit for Zig 0.17 whose largest module is an HTTP server on zio fibers (io_uring, epoll, kqueue). A plain function is a route: its argument list is the routing, the typed input, the 400 for anything that does not fit, and the OpenAPI document. One allocation per request, 4,669 bytes per idle connection, and a wait parks the fiber rather than the thread. Serves HTTP/1.1 and h2c on 8080, TLS 1.3 on 8081, h2c on 8082 and HTTP/2 over TLS with ALPN on 8443 from one process. HTTP/2 and unary gRPC are behind the -Dhttp2 build flag, which this entry builds with; gRPC is unary only, so the streaming profiles are not subscribed. Refuses HTTP/3 and templates on the record, which is why it sits out those profiles.
Achievements
🥇 8 Gold · 🥈 3 Silver · 🥉 3 Bronze. Top three of a field, taken in this entry's own league: the family composite, the same composite among entries written in the same language, and each test profile it is scored on. Every field is the one the badges publish, so a medal and a badge always say the same thing. How medals are awarded.
| Medal | Award | Field | Rank |
|---|---|---|---|
| 🥇 Gold | Family composite | Composite · HTTP/1.1 | 1 of 7 |
| 🥇 Gold | Test profile | Concurrency · Async Delay | 1 of 5 |
| 🥇 Gold | Test profile | Efficiency · Latency-10K | 1 of 5 |
| 🥇 Gold | Test profile | HTTP/2 · Baseline | 1 of 3 |
| 🥇 Gold | Test profile | HTTP/2 · JSON (h2c) | 1 of 4 |
| 🥇 Gold | Test profile | WebSocket · Echo Pipelined | 1 of 7 |
| 🥇 Gold | Test profile | Workload · JSON Comp | 1 of 6 |
| 🥇 Gold | Test profile | Workload · JSON TLS | 1 of 6 |
| 🥈 Silver | Family composite | Composite · HTTP/2 | 2 of 4 |
| 🥈 Silver | Test profile | HTTP/2 · Baseline (h2c) | 2 of 4 |
| 🥈 Silver | Test profile | HTTP/2 · Static | 2 of 3 |
| 🥉 Bronze | Family composite | Composite · WebSocket | 3 of 7 |
| 🥉 Bronze | Test profile | WebSocket · Echo | 3 of 7 |
| 🥉 Bronze | Test profile | Workload · 8Gbit | 3 of 5 |
Composite rank
Each profile of a family is worth 100 to the entry that leads it, and the composite is the sum over the family, less 2.5% for each of routing, middleware, request and response the entry does not do for you - its completeness factor, which the WebSocket and gRPC families do not carry. The field is this entry's own league: engines and reverse proxies are scored apart from frameworks. How it works.
| Family | Rank | Composite |
|---|---|---|
| HTTP/1.1 | 1 of 7 | 7489 |
| HTTP/2 | 2 of 4 | 2369 |
| gRPC | 2 of 2 | 1570 |
| WebSocket | 3 of 7 | 2662 |
Every result
Alpha Round, 33 runs. Requests per second is the best of three; latency, CPU and memory come from that run.
| Category | Profile | Conns | Req/sec | Avg | p99 | CPU | Memory |
|---|---|---|---|---|---|---|---|
| Connection | Baseline | 4,096 | 3,076,550 | 1.33ms | 1.52ms | 6693.6% | 171MiB |
| Connection | Pipelined | 4,096 | 12,006,230 | 5.47ms | 11.00ms | 6548.0% | 140MiB |
| Connection | Short-lived | 4,096 | 2,301,647 | 1.76ms | 10.60ms | 5868.5% | 261MiB |
| Concurrency | Async Delay | 32,000 | 1,973,470 | 15.13ms | 28.00ms | 4898.7% | 1002MiB |
| Efficiency | Latency-10K | 1,024 | 9,983 | 72.6us | 103.0us | 24.9% | 66MiB |
| Efficiency | Latency-1M | 1,024 | 997,605 | 103.9us | 180.0us | 2745.5% | 68MiB |
| Efficiency | Latency-500K/8 | 1,024 | 440,897 | 1158568.3us | 2309120.0us | 793.1% | 49MiB |
| Workload | JSON Comp | 4,096 | 611,376 | 6.69ms | 31.20ms | 6598.4% | 321MiB |
| Workload | JSON Comp | 16,384 | 594,331 | 19.67ms | 179.00ms | 6547.5% | 496MiB |
| Workload | JSON TLS | 4,096 | 1,561,927 | 3.09ms | 309.41ms | 6303.1% | 653MiB |
| Workload | 8Gbit | 512 | 49,266 | 102.7us | 144.0us | 272.5% | 120MiB |
| Database | Async DB | 1,024 | 68,515 | 14.47ms | 59.80ms | 769.1% | 150MiB |
| HTTP/2 | Baseline | 256 | 7,267,874 | 4.06ms | 24.26ms | 6442.7% | 111MiB |
| HTTP/2 | Baseline | 1,024 | 8,912,070 | 14.40ms | 120.50ms | 6164.7% | 227MiB |
| HTTP/2 | Static | 256 | 862,191 | 9.29ms | 25.11ms | 6541.1% | 1.4GiB |
| HTTP/2 | Static | 1,024 | 201,561 | 155.29ms | 253.54ms | 6225.3% | 686MiB |
| HTTP/2 | Baseline (h2c) | 256 | 9,010,310 | 2.67ms | 11.03ms | 6446.2% | 57MiB |
| HTTP/2 | Baseline (h2c) | 1,024 | 7,234,451 | 13.47ms | 46.11ms | 6369.0% | 142MiB |
| HTTP/2 | Baseline (h2c) | 4,096 | 6,873,413 | 56.66ms | 146.15ms | 6440.6% | 253MiB |
| HTTP/2 | JSON (h2c) | 1,024 | 1,409,454 | 22.23ms | 94.60ms | 1507.4% | 359MiB |
| HTTP/2 | JSON (h2c) | 4,096 | 1,387,433 | 87.83ms | 327.18ms | 1787.2% | 894MiB |
| gRPC | Unary | 256 | 6,357,462 | 3.65ms | 9.96ms | 6459.6% | 423MiB |
| gRPC | Unary | 1,024 | 6,706,912 | 10.99ms | 197.47ms | 6382.7% | 1006MiB |
| gRPC | Unary TLS | 256 | 2,126,794 | 12.95ms | 113.54ms | 6405.4% | 626MiB |
| gRPC | Unary TLS | 1,024 | 3,391,337 | 45.16ms | 561.80ms | 6238.6% | 2.1GiB |
| WebSocket | Echo | 512 | 4,111,406 | 123us | 161us | 6575.9% | 47MiB |
| WebSocket | Echo | 4,096 | 3,995,815 | 1.02ms | 1.78ms | 6515.9% | 145MiB |
| WebSocket | Echo | 16,384 | 3,466,526 | 3.98ms | 5.84ms | 6480.0% | 478MiB |
| WebSocket | Echo Pipelined | 512 | 61,071,888 | 133us | 190us | 6309.6% | 47MiB |
| WebSocket | Echo Pipelined | 4,096 | 58,610,864 | 1.12ms | 1.73ms | 6284.8% | 151MiB |
| WebSocket | Echo Pipelined | 16,384 | 50,919,069 | 4.37ms | 6.12ms | 6211.1% | 503MiB |
| WebSocket | Echo Short-lived | 512 | 1,192,006 | 351us | 1.29ms | 3619.4% | 96MiB |
| WebSocket | Echo Short-lived | 4,096 | 2,139,768 | 637us | 2.15ms | 5619.1% | 220MiB |
Compared with
The Zig entries around nilo on the HTTP/1.1 composite, and the one leading them. The last column shows every profile side by side.
| Entry | Composite | vs nilo | |
|---|---|---|---|
| swerver | 7170 | -4% | head to head |
| dusty | 6938 | -7% | head to head |
Compare nilo with any Zig entry · Compare nilo with any entry, in any language · Every Zig entry, ranked
Results updated · How the benchmark is run · The machine · Add or fix an entry