JS web API framework benchmark
Framework x runtime, realistic API workloads. Results folder: full-1
- Each server runs as a single process (no cluster). Every scenario: fresh server, 20s measured x 3 run(s), median reported.
- Load generators (oha, k6) and Postgres/Redis (Docker) share the machine with the server, so absolute numbers depend on the host. Compare rows with each other, not with other benchmarks.
- Database scenarios are usually bounded by Postgres, which narrows the gap between frameworks. CPU-bound scenarios (large-json, bulk, login) show framework and runtime differences most clearly.
- Mixed traffic runs at a fixed arrival rate, so throughput is the same for everyone: compare tail latency and dropped iterations instead.
Overall score
Geometric mean of RPS relative to the best combo in each throughput scenario (100 = best everywhere).
Framework x runtime
| Framework | Node | Bun | Deno |
|---|---|---|---|
| node:http (baseline) | 57.1 | 60.8 | 49.5 |
| Bun.serve (baseline) | – | 78.3 | – |
| Deno.serve (baseline) | – | – | 67.2 |
| Express 5 | 52.6 | 71.7 | 46.9 |
| Fastify | 59.2 | 76.9 | 57.9 |
| Koa | 57.4 | 73.7 | 56.6 |
| Hapi | 50.4 | 66.7 | 46.9 |
| NestJS (Express) | 43.9 | 56.9 | 39.9 |
| NestJS (Fastify) | 51.1 | 61.0 | 49.5 |
| Hono | 60.6 | 86.4 | 69.6 |
| Elysia | 58.9 | 87.3 | 65.7 |
| h3 | 57.4 | 86.6 | 67.9 |
| uWebSockets.js | 79.4 | N/A | – |
| HyperExpress | 74.0 | N/A | – |
GET /plaintext
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | uWebSockets.js on node | 139,732 | 0.4 | 0.761 | 0.87 | 93 | 97 | 0 |
| 2 | Hono on bun | 125,903 | 0.445 | 0.842 | 1.033 | 67 | 99 | 0 |
| 3 | Hono on deno | 123,760 | 0.51 | 0.557 | 0.651 | 102 | 97 | 0 |
| 4 | Elysia on deno | 119,204 | 0.53 | 0.579 | 0.673 | 89 | 97 | 0 |
| 5 | Elysia on bun | 117,899 | 0.483 | 0.854 | 1.14 | 70 | 99 | 0 |
| 6 | h3 on bun | 113,334 | 0.506 | 0.912 | 1.123 | 68 | 99 | 0 |
| 7 | HyperExpress on node | 110,570 | 0.532 | 0.652 | 1.124 | 114 | 98 | 0 |
| 8 | h3 on deno | 105,064 | 0.579 | 0.635 | 1.763 | 172 | 110 | 0 |
| 9 | Deno.serve (baseline) on deno | 102,347 | 0.618 | 0.68 | 0.781 | 102 | 97 | 0 |
| 10 | node:http (baseline) on node | 89,332 | 0.675 | 0.771 | 1.407 | 124 | 97 | 0 |
| 11 | Bun.serve (baseline) on bun | 85,112 | 0.68 | 1.025 | 1.539 | 62 | 99 | 0 |
| 12 | Hono on node | 84,843 | 0.714 | 0.8 | 1.483 | 128 | 98 | 0 |
| 13 | Fastify on bun | 81,445 | 0.709 | 0.973 | 1.682 | 122 | 98 | 0 |
| 14 | Elysia on node | 79,978 | 0.76 | 0.842 | 1.566 | 128 | 98 | 0 |
| 15 | NestJS (Fastify) on bun | 77,389 | 0.774 | 0.878 | 1.593 | 154 | 99 | 0 |
| 16 | Express 5 on bun | 72,984 | 0.82 | 0.951 | 1.697 | 121 | 99 | 0 |
| 17 | Fastify on node | 72,248 | 0.826 | 1.057 | 1.789 | 126 | 98 | 0 |
| 18 | NestJS (Fastify) on node | 71,560 | 0.854 | 0.94 | 1.757 | 184 | 98 | 0 |
| 19 | Koa on bun | 71,151 | 0.846 | 0.982 | 1.733 | 123 | 100 | 0 |
| 20 | NestJS (Express) on bun | 67,681 | 0.889 | 0.995 | 1.818 | 156 | 99 | 0 |
| 21 | Fastify on deno | 67,430 | 0.891 | 0.969 | 2.625 | 196 | 116 | 0 |
| 22 | Koa on node | 59,143 | 1.02 | 1.232 | 2.185 | 132 | 98 | 0 |
| 23 | node:http (baseline) on bun | 58,993 | 1.032 | 1.237 | 2.18 | 95 | 99 | 0 |
| 24 | NestJS (Fastify) on deno | 57,858 | 1.043 | 1.116 | 2.594 | 254 | 116 | 0 |
| 25 | Koa on deno | 57,398 | 1.033 | 1.139 | 2.736 | 196 | 120 | 0 |
| 26 | Hapi on bun | 56,384 | 1.074 | 1.215 | 2.177 | 143 | 100 | 0 |
| 27 | h3 on node | 49,884 | 1.158 | 1.741 | 2.908 | 137 | 98 | 0 |
| 28 | Express 5 on node | 49,366 | 1.233 | 1.457 | 2.519 | 167 | 98 | 0 |
| 29 | Hapi on node | 49,041 | 1.258 | 1.385 | 2.546 | 191 | 98 | 0 |
| 30 | Hapi on deno | 44,848 | 1.281 | 1.414 | 3.366 | 212 | 133 | 0 |
| 31 | Express 5 on deno | 43,379 | 1.396 | 1.493 | 3.125 | 196 | 115 | 0 |
| 32 | NestJS (Express) on node | 42,938 | 1.438 | 1.562 | 2.918 | 183 | 99 | 0 |
| 33 | NestJS (Express) on deno | 40,254 | 1.501 | 1.609 | 3.141 | 235 | 116 | 0 |
| 34 | node:http (baseline) on deno | 40,043 | 1.545 | 1.824 | 2.57 | 173 | 103 | 0 |
GET /json
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | uWebSockets.js on node | 130,406 | 0.434 | 0.819 | 0.939 | 93 | 97 | 0 |
| 2 | HyperExpress on node | 110,096 | 0.534 | 0.659 | 1.125 | 113 | 98 | 0 |
| 3 | Elysia on bun | 96,637 | 0.588 | 1.098 | 1.325 | 70 | 99 | 0 |
| 4 | h3 on deno | 89,962 | 0.682 | 0.757 | 2.129 | 171 | 109 | 0 |
| 5 | node:http (baseline) on node | 89,229 | 0.679 | 0.756 | 1.4 | 124 | 98 | 0 |
| 6 | Hono on bun | 88,477 | 0.649 | 1.106 | 1.479 | 67 | 99 | 0 |
| 7 | Hono on deno | 83,327 | 0.749 | 0.852 | 0.975 | 102 | 97 | 0 |
| 8 | Elysia on deno | 82,234 | 0.772 | 0.86 | 0.981 | 89 | 97 | 0 |
| 9 | h3 on bun | 80,299 | 0.735 | 1.032 | 1.632 | 69 | 99 | 0 |
| 10 | Bun.serve (baseline) on bun | 73,376 | 0.787 | 1.196 | 1.81 | 65 | 99 | 0 |
| 11 | Deno.serve (baseline) on deno | 71,194 | 0.877 | 1.003 | 1.14 | 102 | 97 | 0 |
| 12 | Hono on node | 63,708 | 0.945 | 1.085 | 1.964 | 128 | 98 | 0 |
| 13 | Elysia on node | 61,076 | 1.006 | 1.111 | 2.065 | 129 | 98 | 0 |
| 14 | NestJS (Fastify) on bun | 59,641 | 1.017 | 1.139 | 2.084 | 154 | 99 | 0 |
| 15 | Fastify on node | 58,063 | 1.058 | 1.232 | 2.198 | 127 | 98 | 0 |
| 16 | NestJS (Fastify) on node | 57,658 | 1.071 | 1.17 | 2.193 | 183 | 98 | 0 |
| 17 | Fastify on bun | 57,152 | 1.042 | 1.297 | 2.32 | 133 | 99 | 0 |
| 18 | h3 on node | 56,901 | 1.087 | 1.215 | 2.26 | 126 | 98 | 0 |
| 19 | Express 5 on bun | 55,299 | 1.081 | 1.288 | 2.306 | 118 | 99 | 0 |
| 20 | Koa on bun | 54,752 | 1.109 | 1.262 | 2.262 | 117 | 100 | 0 |
| 21 | NestJS (Express) on bun | 51,880 | 1.163 | 1.311 | 2.369 | 156 | 100 | 0 |
| 22 | NestJS (Fastify) on deno | 51,671 | 1.17 | 1.275 | 2.905 | 254 | 116 | 0 |
| 23 | Fastify on deno | 50,099 | 1.203 | 1.336 | 3.248 | 193 | 115 | 0 |
| 24 | node:http (baseline) on bun | 48,487 | 1.252 | 1.47 | 2.6 | 95 | 99 | 0 |
| 25 | Koa on node | 48,013 | 1.272 | 1.443 | 2.601 | 134 | 98 | 0 |
| 26 | Hapi on bun | 47,570 | 1.27 | 1.489 | 2.58 | 140 | 100 | 0 |
| 27 | Koa on deno | 45,475 | 1.317 | 1.446 | 3.225 | 201 | 118 | 0 |
| 28 | Hapi on node | 40,162 | 1.546 | 1.662 | 3.114 | 195 | 98 | 0 |
| 29 | NestJS (Express) on node | 38,937 | 1.58 | 1.718 | 3.191 | 183 | 99 | 0 |
| 30 | Express 5 on node | 38,515 | 1.582 | 1.816 | 3.18 | 169 | 98 | 0 |
| 31 | node:http (baseline) on deno | 38,328 | 1.591 | 1.877 | 2.58 | 175 | 103 | 0 |
| 32 | Hapi on deno | 38,172 | 1.515 | 1.725 | 3.949 | 209 | 132 | 0 |
| 33 | NestJS (Express) on deno | 38,055 | 1.595 | 1.733 | 3.385 | 236 | 116 | 0 |
| 34 | Express 5 on deno | 35,507 | 1.707 | 1.875 | 3.756 | 196 | 114 | 0 |
GET /json (256 conns)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | uWebSockets.js on node | 140,376 | 1.705 | 2.021 | 3.436 | 93 | 97 | 0 |
| 2 | HyperExpress on node | 101,734 | 2.462 | 2.61 | 4.808 | 115 | 98 | 0 |
| 3 | Elysia on bun | 101,299 | 2.443 | 2.687 | 4.867 | 71 | 99 | 0 |
| 4 | Hono on bun | 91,344 | 2.678 | 3.042 | 5.303 | 68 | 99 | 0 |
| 5 | Hono on deno | 89,120 | 2.891 | 3.052 | 3.51 | 108 | 97 | 0 |
| 6 | Elysia on deno | 83,705 | 2.961 | 3.355 | 3.824 | 94 | 97 | 0 |
| 7 | h3 on bun | 82,597 | 3.019 | 3.351 | 5.954 | 70 | 99 | 0 |
| 8 | Deno.serve (baseline) on deno | 80,500 | 3.076 | 3.508 | 4.004 | 108 | 97 | 0 |
| 9 | h3 on deno | 76,837 | 3.238 | 3.581 | 5.372 | 178 | 108 | 0 |
| 10 | Bun.serve (baseline) on bun | 71,735 | 3.403 | 3.943 | 6.667 | 63 | 99 | 0 |
| 11 | Fastify on bun | 66,574 | 3.775 | 4.294 | 5.223 | 139 | 99 | 0 |
| 12 | Fastify on node | 64,540 | 3.943 | 4.163 | 4.924 | 157 | 98 | 0 |
| 13 | Hono on node | 64,040 | 3.922 | 4.151 | 4.921 | 157 | 98 | 0 |
| 14 | h3 on node | 62,268 | 4.09 | 4.34 | 5.014 | 155 | 98 | 0 |
| 15 | Elysia on node | 61,220 | 4.157 | 4.404 | 5.134 | 159 | 98 | 0 |
| 16 | NestJS (Fastify) on bun | 58,962 | 4.262 | 4.863 | 5.669 | 170 | 99 | 0 |
| 17 | NestJS (Fastify) on node | 56,391 | 4.53 | 4.765 | 5.431 | 190 | 98 | 0 |
| 18 | Express 5 on bun | 56,300 | 4.385 | 5.034 | 5.817 | 139 | 100 | 0 |
| 19 | node:http (baseline) on node | 55,189 | 4.503 | 5.219 | 6.026 | 152 | 97 | 0 |
| 20 | Koa on bun | 54,520 | 4.632 | 5.125 | 5.943 | 146 | 100 | 0 |
| 21 | Fastify on deno | 53,825 | 4.688 | 5.489 | 6.784 | 200 | 104 | 0 |
| 22 | NestJS (Express) on bun | 53,100 | 4.741 | 5.377 | 6.168 | 172 | 100 | 0 |
| 23 | Koa on node | 52,884 | 4.786 | 4.99 | 5.547 | 167 | 99 | 0 |
| 24 | NestJS (Fastify) on deno | 50,482 | 4.938 | 5.767 | 6.942 | 255 | 105 | 0 |
| 25 | node:http (baseline) on bun | 46,906 | 5.37 | 5.972 | 7.161 | 122 | 99 | 0 |
| 26 | Koa on deno | 46,307 | 5.384 | 6.452 | 8.149 | 209 | 106 | 0 |
| 27 | Hapi on bun | 46,002 | 5.498 | 6.109 | 6.855 | 189 | 100 | 0 |
| 28 | Express 5 on node | 43,217 | 5.89 | 6.265 | 6.782 | 172 | 98 | 1 |
| 29 | Hapi on node | 41,075 | 6.201 | 6.529 | 7.256 | 200 | 99 | 1974 |
| 30 | NestJS (Express) on node | 38,666 | 6.536 | 6.978 | 7.765 | 191 | 99 | 4014 |
| 31 | node:http (baseline) on deno | 38,099 | 6.443 | 8.578 | 10.575 | 179 | 104 | 0 |
| 32 | Hapi on deno | 36,531 | 6.654 | 8.811 | 13.085 | 234 | 124 | 0 |
| 33 | Express 5 on deno | 36,075 | 6.74 | 9.17 | 11.553 | 208 | 115 | 0 |
| 34 | NestJS (Express) on deno | 33,951 | 7.201 | 8.945 | 12.308 | 242 | 117 | 0 |
GET /users/:id (Postgres PK lookup)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | Elysia on bun | 11,946 | 5.339 | 6.588 | 8.295 | 115 | 99 | 0 |
| 2 | Hono on bun | 11,934 | 5.314 | 6.618 | 8.334 | 114 | 99 | 0 |
| 3 | NestJS (Fastify) on bun | 11,766 | 5.383 | 6.731 | 8.499 | 189 | 100 | 0 |
| 4 | Fastify on bun | 11,756 | 5.426 | 6.621 | 8.437 | 162 | 99 | 0 |
| 5 | Koa on bun | 11,605 | 5.462 | 6.844 | 8.636 | 158 | 100 | 0 |
| 6 | NestJS (Express) on bun | 11,601 | 5.452 | 6.933 | 8.683 | 192 | 100 | 0 |
| 7 | h3 on bun | 11,593 | 5.475 | 6.893 | 8.638 | 109 | 99 | 0 |
| 8 | Hapi on bun | 11,587 | 5.472 | 6.954 | 8.736 | 170 | 100 | 0 |
| 9 | Express 5 on bun | 11,443 | 5.545 | 6.998 | 8.681 | 155 | 100 | 0 |
| 10 | Bun.serve (baseline) on bun | 11,244 | 5.662 | 7.04 | 8.84 | 107 | 99 | 0 |
| 11 | node:http (baseline) on bun | 10,137 | 6.215 | 7.902 | 9.731 | 118 | 100 | 0 |
| 12 | h3 on deno | 8,948 | 7.611 | 9.102 | 10.341 | 199 | 102 | 0 |
| 13 | Fastify on deno | 8,909 | 7.274 | 9.066 | 10.672 | 221 | 104 | 0 |
| 14 | uWebSockets.js on node | 8,810 | 7.277 | 8.301 | 10.683 | 179 | 101 | 0 |
| 15 | Koa on deno | 8,725 | 7.398 | 9.105 | 11.132 | 226 | 105 | 0 |
| 16 | Hapi on deno | 8,721 | 7.339 | 9.337 | 11.903 | 237 | 109 | 0 |
| 17 | Elysia on deno | 8,719 | 7.804 | 9.297 | 10.58 | 177 | 101 | 0 |
| 18 | Hono on deno | 8,718 | 7.794 | 9.305 | 10.676 | 189 | 101 | 0 |
| 19 | NestJS (Fastify) on deno | 8,651 | 7.397 | 8.812 | 10.806 | 279 | 104 | 0 |
| 20 | Hono on node | 8,643 | 7.428 | 8.524 | 10.941 | 212 | 101 | 0 |
| 21 | Fastify on node | 8,618 | 7.427 | 8.504 | 10.93 | 208 | 101 | 0 |
| 22 | Elysia on node | 8,618 | 7.438 | 8.556 | 10.861 | 210 | 101 | 0 |
| 23 | NestJS (Fastify) on node | 8,609 | 7.48 | 8.629 | 10.996 | 263 | 101 | 0 |
| 24 | NestJS (Express) on node | 8,588 | 7.468 | 8.971 | 11.175 | 253 | 101 | 0 |
| 25 | HyperExpress on node | 8,585 | 7.469 | 8.633 | 11.115 | 194 | 103 | 0 |
| 26 | Deno.serve (baseline) on deno | 8,576 | 7.939 | 9.427 | 10.81 | 188 | 100 | 0 |
| 27 | Hapi on node | 8,571 | 7.44 | 8.994 | 11.403 | 191 | 101 | 0 |
| 28 | h3 on node | 8,536 | 7.543 | 8.666 | 11.038 | 209 | 101 | 0 |
| 29 | Express 5 on node | 8,521 | 7.535 | 9.018 | 11.203 | 196 | 101 | 0 |
| 30 | Express 5 on deno | 8,508 | 7.414 | 9.229 | 11.248 | 215 | 104 | 0 |
| 31 | NestJS (Express) on deno | 8,504 | 7.502 | 8.953 | 11.002 | 256 | 105 | 0 |
| 32 | Koa on node | 8,502 | 7.523 | 8.975 | 11.322 | 202 | 101 | 0 |
| 33 | node:http (baseline) on deno | 8,161 | 7.954 | 9.688 | 11.419 | 180 | 102 | 0 |
| 34 | node:http (baseline) on node | 8,012 | 7.995 | 9.803 | 11.745 | 175 | 101 | 0 |
GET /posts (JOIN + pagination)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | HyperExpress on node | 6,157 | 9.5 | 17.846 | 29.962 | 201 | 93 | 0 |
| 2 | h3 on deno | 5,870 | 10.121 | 17.344 | 30.19 | 194 | 92 | 0 |
| 3 | uWebSockets.js on node | 5,863 | 9.769 | 18.586 | 34.585 | 195 | 92 | 0 |
| 4 | Elysia on bun | 5,690 | 7.526 | 25.497 | 52.819 | 113 | 68 | 0 |
| 5 | Hono on bun | 5,661 | 8.346 | 24.054 | 49.387 | 111 | 72 | 0 |
| 6 | Hono on deno | 5,571 | 10.548 | 18.775 | 34.279 | 181 | 90 | 0 |
| 7 | Fastify on bun | 5,453 | 8.938 | 24.544 | 49.008 | 151 | 75 | 0 |
| 8 | h3 on bun | 5,432 | 8.795 | 25.047 | 50.138 | 105 | 71 | 0 |
| 9 | NestJS (Fastify) on bun | 5,424 | 9.78 | 23.198 | 44.751 | 202 | 83 | 0 |
| 10 | Elysia on node | 5,372 | 11.294 | 19.369 | 31.33 | 210 | 91 | 0 |
| 11 | Koa on bun | 5,371 | 9.723 | 24.255 | 47.978 | 156 | 79 | 0 |
| 12 | Hono on node | 5,366 | 11.094 | 19.404 | 34.054 | 209 | 90 | 0 |
| 13 | Express 5 on bun | 5,311 | 9.175 | 25.273 | 49.815 | 156 | 77 | 0 |
| 14 | NestJS (Express) on bun | 5,311 | 9.893 | 22.776 | 43.179 | 196 | 85 | 0 |
| 15 | Elysia on deno | 5,293 | 11.18 | 19.546 | 35.524 | 180 | 91 | 0 |
| 16 | NestJS (Fastify) on deno | 5,225 | 11.605 | 19.579 | 33.782 | 256 | 95 | 0 |
| 17 | NestJS (Fastify) on node | 5,140 | 11.645 | 19.424 | 33.805 | 274 | 91 | 0 |
| 18 | Fastify on node | 5,129 | 11.723 | 20.831 | 33.965 | 210 | 96 | 0 |
| 19 | Koa on node | 5,104 | 11.811 | 20.636 | 34.024 | 217 | 91 | 0 |
| 20 | Koa on deno | 5,084 | 11.9 | 19.668 | 33.459 | 219 | 94 | 0 |
| 21 | Deno.serve (baseline) on deno | 5,076 | 11.701 | 20.268 | 36.674 | 179 | 91 | 0 |
| 22 | Fastify on deno | 5,073 | 11.729 | 20.682 | 34.351 | 207 | 98 | 0 |
| 23 | NestJS (Express) on node | 4,958 | 12.563 | 19.033 | 29.603 | 252 | 94 | 0 |
| 24 | Express 5 on node | 4,835 | 12.703 | 19.755 | 31.35 | 216 | 97 | 0 |
| 25 | Bun.serve (baseline) on bun | 4,835 | 10.335 | 27.736 | 55.788 | 98 | 72 | 0 |
| 26 | NestJS (Express) on deno | 4,831 | 12.834 | 18.681 | 28.339 | 247 | 98 | 0 |
| 27 | Express 5 on deno | 4,823 | 12.747 | 19.281 | 28.917 | 208 | 101 | 0 |
| 28 | Hapi on bun | 4,790 | 12.533 | 20.62 | 35.562 | 221 | 109 | 0 |
| 29 | h3 on node | 4,616 | 13.206 | 21.39 | 36.637 | 209 | 89 | 0 |
| 30 | Hapi on deno | 4,511 | 13.631 | 19.702 | 26.41 | 260 | 106 | 0 |
| 31 | node:http (baseline) on node | 4,354 | 14.358 | 21.335 | 28.538 | 202 | 94 | 0 |
| 32 | Hapi on node | 4,223 | 14.895 | 20.466 | 28.46 | 276 | 124 | 0 |
| 33 | node:http (baseline) on deno | 3,922 | 15.419 | 23.843 | 44.801 | 184 | 93 | 0 |
| 34 | node:http (baseline) on bun | 3,810 | 13.356 | 31.968 | 71.938 | 119 | 70 | 0 |
POST /users (validate + INSERT)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | Hono on bun | 11,653 | 5.397 | 6.856 | 8.93 | 115 | 97 | 0 |
| 2 | Elysia on bun | 11,651 | 5.344 | 6.757 | 8.592 | 119 | 97 | 0 |
| 3 | Fastify on bun | 11,413 | 5.516 | 7.029 | 8.932 | 186 | 98 | 0 |
| 4 | h3 on bun | 11,388 | 5.529 | 7.143 | 9.312 | 120 | 97 | 0 |
| 5 | Bun.serve (baseline) on bun | 11,201 | 5.653 | 7.141 | 9.087 | 106 | 97 | 0 |
| 6 | Koa on bun | 11,121 | 5.622 | 7.293 | 9.15 | 176 | 98 | 0 |
| 7 | Express 5 on bun | 11,062 | 5.647 | 7.215 | 9.193 | 184 | 98 | 0 |
| 8 | Hapi on bun | 11,031 | 5.7 | 7.364 | 9.326 | 204 | 99 | 0 |
| 9 | NestJS (Express) on bun | 10,735 | 5.844 | 7.59 | 9.551 | 235 | 99 | 0 |
| 10 | NestJS (Fastify) on bun | 10,680 | 5.852 | 7.559 | 9.518 | 228 | 98 | 0 |
| 11 | node:http (baseline) on bun | 9,991 | 6.341 | 8.147 | 10.345 | 133 | 99 | 0 |
| 12 | h3 on deno | 9,152 | 7.366 | 9.091 | 10.582 | 212 | 102 | 0 |
| 13 | Fastify on deno | 8,801 | 7.317 | 8.823 | 10.959 | 222 | 103 | 0 |
| 14 | Hono on deno | 8,746 | 7.758 | 9.476 | 10.924 | 203 | 100 | 0 |
| 15 | HyperExpress on node | 8,721 | 7.32 | 8.351 | 10.706 | 196 | 100 | 0 |
| 16 | uWebSockets.js on node | 8,675 | 7.338 | 8.408 | 10.748 | 184 | 100 | 0 |
| 17 | Koa on deno | 8,666 | 7.427 | 8.945 | 11.065 | 237 | 104 | 0 |
| 18 | NestJS (Fastify) on deno | 8,608 | 7.472 | 9.037 | 10.979 | 290 | 104 | 0 |
| 19 | Elysia on deno | 8,582 | 7.841 | 9.65 | 11.469 | 187 | 100 | 0 |
| 20 | Deno.serve (baseline) on deno | 8,534 | 8.002 | 9.637 | 11.036 | 192 | 100 | 0 |
| 21 | Hono on node | 8,504 | 7.571 | 8.529 | 10.706 | 219 | 100 | 0 |
| 22 | Fastify on node | 8,399 | 7.606 | 8.623 | 11.242 | 218 | 101 | 0 |
| 23 | Express 5 on deno | 8,383 | 7.608 | 9.155 | 11.469 | 230 | 104 | 0 |
| 24 | Hapi on deno | 8,320 | 7.674 | 9.628 | 12.448 | 244 | 111 | 0 |
| 25 | h3 on node | 8,282 | 7.667 | 8.977 | 11.607 | 205 | 100 | 0 |
| 26 | Express 5 on node | 8,266 | 7.749 | 8.901 | 11.385 | 219 | 100 | 0 |
| 27 | Koa on node | 8,264 | 7.739 | 9.089 | 11.617 | 213 | 101 | 0 |
| 28 | NestJS (Fastify) on node | 8,264 | 7.783 | 8.832 | 11.342 | 273 | 101 | 0 |
| 29 | Elysia on node | 8,247 | 7.7 | 9.497 | 12.154 | 239 | 103 | 0 |
| 30 | Hapi on node | 8,211 | 7.775 | 9.042 | 11.764 | 247 | 102 | 0 |
| 31 | NestJS (Express) on deno | 8,189 | 7.789 | 9.373 | 11.393 | 270 | 105 | 0 |
| 32 | NestJS (Express) on node | 8,159 | 7.854 | 9.173 | 11.619 | 270 | 101 | 0 |
| 33 | node:http (baseline) on deno | 7,996 | 8.127 | 9.557 | 11.483 | 210 | 102 | 0 |
| 34 | node:http (baseline) on node | 7,151 | 8.801 | 10.929 | 13.986 | 207 | 100 | 0 |
PATCH /users/:id (validate + UPDATE)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | Elysia on bun | 12,437 | 5.079 | 6.315 | 8.07 | 119 | 98 | 0 |
| 2 | Hono on bun | 12,319 | 5.14 | 6.405 | 8.194 | 117 | 99 | 0 |
| 3 | h3 on bun | 12,186 | 5.158 | 6.309 | 8.134 | 114 | 98 | 0 |
| 4 | Fastify on bun | 12,178 | 5.172 | 6.48 | 8.424 | 170 | 99 | 0 |
| 5 | NestJS (Fastify) on bun | 11,755 | 5.347 | 6.792 | 8.712 | 218 | 99 | 0 |
| 6 | Koa on bun | 11,747 | 5.371 | 6.801 | 8.613 | 166 | 99 | 0 |
| 7 | Express 5 on bun | 11,715 | 5.386 | 6.786 | 8.699 | 166 | 99 | 0 |
| 8 | Bun.serve (baseline) on bun | 11,694 | 5.4 | 6.719 | 8.557 | 108 | 98 | 0 |
| 9 | Hapi on bun | 11,516 | 5.471 | 7.012 | 8.893 | 177 | 99 | 0 |
| 10 | NestJS (Express) on bun | 11,456 | 5.488 | 7.027 | 8.872 | 211 | 99 | 0 |
| 11 | node:http (baseline) on bun | 10,213 | 6.151 | 7.854 | 9.864 | 129 | 100 | 0 |
| 12 | Hono on deno | 9,083 | 7.412 | 8.978 | 10.387 | 187 | 100 | 0 |
| 13 | Fastify on deno | 9,000 | 7.102 | 8.658 | 11.216 | 222 | 106 | 0 |
| 14 | Elysia on deno | 8,914 | 7.555 | 9.113 | 10.678 | 205 | 101 | 0 |
| 15 | NestJS (Fastify) on deno | 8,866 | 7.263 | 8.72 | 10.461 | 287 | 104 | 0 |
| 16 | Koa on deno | 8,795 | 7.306 | 8.788 | 10.967 | 234 | 105 | 0 |
| 17 | Deno.serve (baseline) on deno | 8,742 | 7.674 | 9.321 | 10.953 | 192 | 103 | 0 |
| 18 | Hono on node | 8,704 | 7.347 | 8.36 | 10.681 | 216 | 101 | 0 |
| 19 | Fastify on node | 8,695 | 7.363 | 8.383 | 10.727 | 200 | 101 | 0 |
| 20 | h3 on deno | 8,671 | 7.811 | 9.409 | 10.809 | 210 | 103 | 0 |
| 21 | Koa on node | 8,657 | 7.4 | 8.463 | 10.671 | 215 | 101 | 0 |
| 22 | uWebSockets.js on node | 8,622 | 7.391 | 8.443 | 10.953 | 203 | 103 | 0 |
| 23 | HyperExpress on node | 8,611 | 7.432 | 8.513 | 11.013 | 205 | 103 | 0 |
| 24 | Express 5 on deno | 8,574 | 7.442 | 8.884 | 11.137 | 227 | 105 | 0 |
| 25 | NestJS (Fastify) on node | 8,566 | 7.483 | 8.446 | 10.68 | 268 | 101 | 0 |
| 26 | Elysia on node | 8,549 | 7.426 | 8.799 | 11.431 | 245 | 104 | 0 |
| 27 | Hapi on deno | 8,546 | 7.383 | 9.478 | 12.245 | 233 | 114 | 0 |
| 28 | NestJS (Express) on deno | 8,541 | 7.458 | 8.964 | 11.03 | 291 | 106 | 0 |
| 29 | Express 5 on node | 8,422 | 7.58 | 8.77 | 11.146 | 197 | 101 | 0 |
| 30 | h3 on node | 8,415 | 7.593 | 8.736 | 11.31 | 220 | 104 | 0 |
| 31 | NestJS (Express) on node | 8,391 | 7.608 | 8.885 | 11.351 | 267 | 102 | 0 |
| 32 | node:http (baseline) on deno | 8,386 | 7.648 | 9.143 | 10.934 | 204 | 103 | 0 |
| 33 | Hapi on node | 8,356 | 7.642 | 9.034 | 11.686 | 242 | 103 | 0 |
| 34 | node:http (baseline) on node | 8,149 | 7.884 | 8.943 | 11.271 | 202 | 101 | 0 |
GET /me/feed (request-id, logger, CORS, JWT, query)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | h3 on bun | 11,935 | 5.302 | 6.711 | 8.322 | 126 | 111 | 0 |
| 2 | Elysia on bun | 11,547 | 5.493 | 6.851 | 8.42 | 127 | 110 | 0 |
| 3 | Fastify on bun | 11,304 | 5.612 | 7.088 | 8.727 | 184 | 111 | 0 |
| 4 | Hono on bun | 11,148 | 5.71 | 7.197 | 8.903 | 126 | 111 | 0 |
| 5 | NestJS (Fastify) on bun | 11,112 | 5.679 | 7.287 | 9.104 | 213 | 111 | 0 |
| 6 | Bun.serve (baseline) on bun | 11,061 | 5.726 | 7.237 | 8.846 | 122 | 111 | 0 |
| 7 | Express 5 on bun | 10,983 | 5.756 | 7.333 | 9.044 | 158 | 110 | 0 |
| 8 | Koa on bun | 10,974 | 5.767 | 7.326 | 9.049 | 181 | 111 | 0 |
| 9 | NestJS (Express) on bun | 10,931 | 5.776 | 7.357 | 9.158 | 206 | 110 | 0 |
| 10 | Hapi on bun | 10,867 | 5.82 | 7.428 | 9.304 | 197 | 111 | 0 |
| 11 | node:http (baseline) on bun | 9,468 | 6.7 | 8.559 | 10.509 | 143 | 112 | 0 |
| 12 | uWebSockets.js on node | 8,439 | 7.559 | 9.621 | 11.523 | 203 | 107 | 0 |
| 13 | Elysia on node | 8,305 | 7.697 | 9.723 | 11.619 | 219 | 103 | 0 |
| 14 | HyperExpress on node | 8,267 | 7.705 | 9.823 | 11.73 | 203 | 106 | 0 |
| 15 | Koa on node | 8,236 | 7.755 | 9.873 | 11.731 | 231 | 102 | 0 |
| 16 | Fastify on deno | 8,202 | 8.018 | 9.603 | 11.55 | 268 | 111 | 0 |
| 17 | Fastify on node | 8,184 | 7.798 | 9.946 | 11.903 | 234 | 106 | 0 |
| 18 | Hapi on node | 8,105 | 7.891 | 10.029 | 11.844 | 209 | 102 | 0 |
| 19 | NestJS (Fastify) on deno | 8,066 | 8.126 | 9.709 | 11.724 | 328 | 112 | 0 |
| 20 | Express 5 on node | 8,015 | 7.956 | 10.11 | 11.958 | 219 | 101 | 0 |
| 21 | h3 on node | 8,013 | 7.987 | 10.12 | 11.918 | 214 | 102 | 0 |
| 22 | NestJS (Fastify) on node | 8,011 | 7.945 | 10.053 | 11.926 | 271 | 102 | 0 |
| 23 | Elysia on deno | 7,994 | 8.006 | 9.282 | 11.523 | 312 | 108 | 0 |
| 24 | Koa on deno | 7,915 | 8.251 | 9.779 | 11.839 | 268 | 111 | 0 |
| 25 | Deno.serve (baseline) on deno | 7,859 | 8.126 | 9.489 | 11.676 | 308 | 107 | 0 |
| 26 | Hono on deno | 7,808 | 8.126 | 9.621 | 11.84 | 282 | 109 | 0 |
| 27 | Hapi on deno | 7,783 | 8.336 | 10.167 | 12.748 | 251 | 117 | 0 |
| 28 | h3 on deno | 7,765 | 8.211 | 9.769 | 12.516 | 289 | 110 | 0 |
| 29 | Express 5 on deno | 7,732 | 8.535 | 10.208 | 12.411 | 253 | 112 | 0 |
| 30 | NestJS (Express) on deno | 7,694 | 8.543 | 10.058 | 12.273 | 294 | 112 | 0 |
| 31 | Hono on node | 7,676 | 8.295 | 10.624 | 12.597 | 217 | 101 | 0 |
| 32 | NestJS (Express) on node | 7,654 | 8.309 | 10.775 | 12.914 | 268 | 102 | 0 |
| 33 | node:http (baseline) on node | 7,639 | 8.356 | 10.647 | 12.67 | 212 | 106 | 0 |
| 34 | node:http (baseline) on deno | 7,422 | 8.854 | 10.746 | 13.217 | 230 | 114 | 0 |
GET /cache/posts/:id (Redis cache-aside)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | uWebSockets.js on node | 63,538 | 0.991 | 1.2 | 1.45 | 161 | 94 | 0 |
| 2 | HyperExpress on node | 53,215 | 1.147 | 1.49 | 1.762 | 166 | 95 | 0 |
| 3 | h3 on bun | 47,332 | 1.276 | 1.722 | 2.248 | 104 | 97 | 0 |
| 4 | Elysia on bun | 45,962 | 1.331 | 1.756 | 2.269 | 109 | 97 | 0 |
| 5 | Bun.serve (baseline) on bun | 43,525 | 1.408 | 1.854 | 2.414 | 100 | 97 | 0 |
| 6 | Hono on bun | 43,021 | 1.398 | 1.899 | 2.516 | 111 | 98 | 0 |
| 7 | h3 on deno | 41,905 | 1.421 | 1.881 | 2.646 | 184 | 100 | 0 |
| 8 | Fastify on bun | 40,542 | 1.488 | 1.988 | 2.548 | 159 | 98 | 0 |
| 9 | Fastify on node | 39,336 | 1.516 | 2.049 | 2.296 | 172 | 98 | 0 |
| 10 | Elysia on deno | 39,261 | 1.551 | 1.975 | 2.319 | 160 | 95 | 0 |
| 11 | Deno.serve (baseline) on deno | 38,864 | 1.573 | 1.985 | 2.322 | 155 | 95 | 0 |
| 12 | NestJS (Fastify) on bun | 38,450 | 1.545 | 2.128 | 2.787 | 187 | 100 | 0 |
| 13 | Hono on node | 37,602 | 1.582 | 2.193 | 2.574 | 180 | 98 | 0 |
| 14 | h3 on node | 37,430 | 1.594 | 2.17 | 2.505 | 207 | 99 | 0 |
| 15 | Koa on bun | 37,122 | 1.594 | 2.21 | 2.889 | 150 | 101 | 0 |
| 16 | Hono on deno | 36,885 | 1.641 | 2.113 | 2.458 | 157 | 95 | 0 |
| 17 | Elysia on node | 36,844 | 1.639 | 2.206 | 2.588 | 182 | 97 | 0 |
| 18 | Express 5 on bun | 36,485 | 1.64 | 2.18 | 2.827 | 148 | 101 | 0 |
| 19 | NestJS (Fastify) on deno | 36,409 | 1.67 | 2.047 | 2.92 | 255 | 110 | 0 |
| 20 | NestJS (Fastify) on node | 36,335 | 1.638 | 2.244 | 2.632 | 212 | 98 | 0 |
| 21 | Koa on node | 36,254 | 1.64 | 2.242 | 2.546 | 193 | 99 | 0 |
| 22 | NestJS (Express) on bun | 34,973 | 1.699 | 2.303 | 3.005 | 185 | 101 | 0 |
| 23 | Hapi on bun | 34,670 | 1.691 | 2.346 | 3.018 | 170 | 102 | 0 |
| 24 | Fastify on deno | 34,235 | 1.752 | 2.385 | 3.362 | 197 | 109 | 0 |
| 25 | Koa on deno | 32,215 | 1.885 | 2.177 | 3.478 | 204 | 112 | 0 |
| 26 | Hapi on node | 31,445 | 1.883 | 2.568 | 2.923 | 219 | 99 | 0 |
| 27 | Express 5 on node | 30,352 | 1.988 | 2.583 | 2.966 | 173 | 99 | 0 |
| 28 | node:http (baseline) on node | 30,200 | 1.976 | 2.68 | 3.154 | 171 | 98 | 0 |
| 29 | Hapi on deno | 29,358 | 1.97 | 2.778 | 4.753 | 213 | 128 | 0 |
| 30 | node:http (baseline) on deno | 28,117 | 2.165 | 2.806 | 3.675 | 182 | 102 | 0 |
| 31 | NestJS (Express) on node | 27,869 | 2.162 | 2.797 | 3.209 | 250 | 100 | 0 |
| 32 | node:http (baseline) on bun | 27,495 | 2.25 | 2.953 | 3.944 | 122 | 101 | 0 |
| 33 | NestJS (Express) on deno | 26,179 | 2.309 | 2.555 | 4.054 | 240 | 114 | 0 |
| 34 | Express 5 on deno | 25,191 | 2.426 | 2.588 | 4.486 | 202 | 113 | 0 |
GET /large-json (~100KB serialize)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | Hono on bun | 4,259 | 14.734 | 15.666 | 29.211 | 122 | 112 | 0 |
| 2 | Elysia on bun | 4,257 | 14.726 | 15.616 | 29.222 | 93 | 108 | 0 |
| 3 | h3 on bun | 4,219 | 14.86 | 15.651 | 29.522 | 116 | 112 | 0 |
| 4 | NestJS (Fastify) on bun | 4,126 | 15.317 | 16.272 | 20.77 | 243 | 103 | 0 |
| 5 | Koa on bun | 4,059 | 15.441 | 16.578 | 30.351 | 277 | 104 | 0 |
| 6 | Fastify on bun | 3,977 | 15.741 | 16.763 | 31.142 | 191 | 105 | 0 |
| 7 | Bun.serve (baseline) on bun | 3,855 | 16.315 | 17.247 | 32.306 | 79 | 109 | 0 |
| 8 | node:http (baseline) on bun | 3,232 | 19.514 | 20.521 | 38.386 | 143 | 107 | 0 |
| 9 | NestJS (Express) on bun | 3,000 | 20.855 | 22.1 | 41.355 | 239 | 105 | 0 |
| 10 | Express 5 on bun | 2,978 | 21.014 | 22.216 | 41.718 | 193 | 107 | 0 |
| 11 | Hapi on bun | 2,789 | 21.463 | 33.332 | 40.631 | 533 | 292 | 0 |
| 12 | Hono on deno | 2,697 | 23.78 | 24.139 | 24.919 | 199 | 100 | 0 |
| 13 | HyperExpress on node | 2,605 | 24.154 | 24.534 | 48.215 | 169 | 100 | 0 |
| 14 | uWebSockets.js on node | 2,532 | 24.874 | 25.213 | 49.654 | 162 | 100 | 0 |
| 15 | Elysia on deno | 2,490 | 25.799 | 26.201 | 27.139 | 192 | 100 | 0 |
| 16 | Deno.serve (baseline) on deno | 2,489 | 25.653 | 26.441 | 26.874 | 177 | 100 | 0 |
| 17 | Hono on node | 2,462 | 25.561 | 26.141 | 50.885 | 215 | 101 | 0 |
| 18 | Elysia on node | 2,449 | 25.676 | 26.335 | 51.162 | 241 | 101 | 0 |
| 19 | NestJS (Fastify) on node | 2,440 | 25.774 | 26.519 | 51.394 | 309 | 101 | 0 |
| 20 | NestJS (Fastify) on deno | 2,401 | 26.72 | 27.156 | 28.867 | 406 | 112 | 0 |
| 21 | Fastify on node | 2,364 | 26.575 | 27.368 | 52.859 | 208 | 101 | 0 |
| 22 | Fastify on deno | 2,357 | 27.081 | 27.829 | 29.199 | 369 | 112 | 0 |
| 23 | h3 on node | 2,352 | 26.738 | 27.459 | 53.097 | 260 | 101 | 0 |
| 24 | Koa on node | 2,340 | 26.838 | 27.663 | 53.516 | 229 | 101 | 0 |
| 25 | Koa on deno | 2,249 | 28.294 | 29.158 | 32.971 | 349 | 111 | 0 |
| 26 | node:http (baseline) on deno | 2,087 | 30.179 | 31.223 | 46.008 | 408 | 103 | 0 |
| 27 | Express 5 on node | 2,074 | 30.483 | 31.098 | 60.499 | 223 | 101 | 0 |
| 28 | node:http (baseline) on node | 2,043 | 30.743 | 31.907 | 61.206 | 212 | 100 | 0 |
| 29 | NestJS (Express) on node | 2,042 | 30.829 | 31.249 | 61.566 | 234 | 101 | 0 |
| 30 | Hapi on node | 1,545 | 39.58 | 47.99 | 61.579 | 439 | 272 | 0 |
| 31 | h3 on deno | 1,414 | 45.107 | 45.611 | 51.636 | 233 | 101 | 0 |
| 32 | Express 5 on deno | 948 | 66.474 | 72.059 | 76.278 | 352 | 104 | 0 |
| 33 | NestJS (Express) on deno | 947 | 67.389 | 67.942 | 77.138 | 347 | 105 | 0 |
| 34 | Hapi on deno | 795 | 79.418 | 94.882 | 148.825 | 537 | 112 | 0 |
POST /bulk (parse + validate ~100KB)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | Bun.serve (baseline) on bun | 7,125 | 8.754 | 9.378 | 17.45 | 90 | 110 | 0 |
| 2 | h3 on bun | 7,116 | 8.795 | 9.378 | 17.489 | 110 | 111 | 0 |
| 3 | Koa on bun | 6,484 | 9.615 | 10.414 | 19.087 | 190 | 110 | 0 |
| 4 | Express 5 on bun | 6,446 | 9.655 | 10.529 | 19.113 | 181 | 112 | 0 |
| 5 | Deno.serve (baseline) on deno | 6,263 | 10.208 | 10.521 | 10.984 | 179 | 100 | 0 |
| 6 | Hapi on bun | 6,145 | 10.141 | 10.898 | 20.078 | 209 | 109 | 0 |
| 7 | Fastify on bun | 6,088 | 10.275 | 10.896 | 20.376 | 187 | 105 | 0 |
| 8 | Hono on bun | 6,005 | 10.414 | 11.199 | 20.64 | 109 | 113 | 0 |
| 9 | h3 on deno | 5,735 | 10.781 | 12.881 | 15.813 | 309 | 113 | 0 |
| 10 | Elysia on bun | 5,460 | 11.496 | 12.071 | 22.808 | 110 | 103 | 0 |
| 11 | node:http (baseline) on bun | 5,309 | 11.954 | 12.917 | 14.374 | 161 | 114 | 0 |
| 12 | HyperExpress on node | 5,267 | 12.061 | 12.344 | 13.065 | 286 | 100 | 0 |
| 13 | uWebSockets.js on node | 5,182 | 12.147 | 12.485 | 21.482 | 216 | 104 | 0 |
| 14 | h3 on node | 5,042 | 12.59 | 12.879 | 13.919 | 245 | 101 | 0 |
| 15 | Koa on node | 5,024 | 12.548 | 12.934 | 24.805 | 179 | 101 | 0 |
| 16 | Express 5 on node | 5,014 | 12.539 | 12.987 | 24.78 | 240 | 101 | 0 |
| 17 | Koa on deno | 4,667 | 14.157 | 14.88 | 17.933 | 354 | 110 | 0 |
| 18 | node:http (baseline) on deno | 4,659 | 12.827 | 19.227 | 22.015 | 264 | 106 | 0 |
| 19 | Hono on deno | 4,651 | 13.731 | 14.228 | 14.66 | 188 | 100 | 0 |
| 20 | node:http (baseline) on node | 4,510 | 14.105 | 14.555 | 16.587 | 176 | 101 | 0 |
| 21 | Hapi on node | 4,383 | 13.752 | 17.75 | 23.276 | 318 | 121 | 0 |
| 22 | Express 5 on deno | 4,029 | 15.603 | 17.954 | 20.459 | 350 | 132 | 0 |
| 23 | Hono on node | 3,747 | 16.88 | 17.244 | 33.284 | 184 | 101 | 0 |
| 24 | Hapi on deno | 3,569 | 17.654 | 23.05 | 31.765 | 376 | 160 | 0 |
| 25 | Fastify on deno | 3,456 | 18.571 | 19.791 | 22.329 | 260 | 103 | 0 |
| 26 | Fastify on node | 3,345 | 18.903 | 19.25 | 37.331 | 213 | 100 | 0 |
| 27 | Elysia on deno | 3,024 | 21.107 | 21.54 | 23.971 | 315 | 101 | 0 |
| 28 | Elysia on node | 2,680 | 23.567 | 24.007 | 46.533 | 372 | 102 | 0 |
| 29 | NestJS (Express) on node | 797 | 78.155 | 82.525 | 156.201 | 570 | 103 | 0 |
| 30 | NestJS (Fastify) on node | 784 | 80.139 | 81.737 | 160.612 | 196 | 102 | 0 |
| 31 | NestJS (Express) on deno | 650 | 101.103 | 131.357 | 186.927 | 651 | 148 | 0 |
| 32 | NestJS (Fastify) on deno | 605 | 103.459 | 135.292 | 204.805 | 610 | 144 | 0 |
| 33 | NestJS (Express) on bun | 510 | 123.883 | 131.509 | 242.594 | 244 | 112 | 0 |
| 34 | NestJS (Fastify) on bun | 493 | 128.547 | 134.746 | 253.593 | 244 | 113 | 0 |
POST /auth/login (scrypt + JWT sign)
Bar = requests per second (longer is better). Right column shows p99 latency.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | h3 on bun | 968 | 58.844 | 117.64 | 185.89 | 159 | 720 | 0 |
| 2 | Hono on bun | 871 | 64.699 | 133.512 | 210.284 | 150 | 723 | 0 |
| 3 | NestJS (Fastify) on bun | 860 | 66.214 | 133.088 | 206.872 | 240 | 725 | 0 |
| 4 | Fastify on bun | 853 | 66.915 | 132.747 | 208.939 | 189 | 726 | 0 |
| 5 | Elysia on bun | 847 | 66.253 | 136.315 | 215.231 | 189 | 722 | 0 |
| 6 | NestJS (Express) on bun | 845 | 67.243 | 136.381 | 213.948 | 256 | 728 | 0 |
| 7 | Koa on bun | 843 | 67.235 | 135.358 | 219.001 | 198 | 726 | 0 |
| 8 | Hapi on bun | 833 | 68.216 | 137.551 | 215.96 | 225 | 724 | 0 |
| 9 | Express 5 on bun | 816 | 69.429 | 138.626 | 223.398 | 202 | 725 | 0 |
| 10 | Bun.serve (baseline) on bun | 761 | 74.605 | 151.557 | 237.955 | 160 | 722 | 0 |
| 11 | h3 on deno | 728 | 89.337 | 131.029 | 166.181 | 328 | 743 | 0 |
| 12 | node:http (baseline) on bun | 652 | 86.798 | 177.573 | 284.334 | 181 | 733 | 0 |
| 13 | Hono on deno | 608 | 106.754 | 144.444 | 176.697 | 322 | 746 | 0 |
| 14 | Koa on deno | 603 | 108.215 | 144.329 | 183.01 | 348 | 748 | 0 |
| 15 | Hapi on deno | 601 | 108.358 | 147.225 | 184.997 | 353 | 747 | 0 |
| 16 | NestJS (Fastify) on deno | 598 | 108.65 | 144.837 | 181.888 | 377 | 746 | 0 |
| 17 | Elysia on deno | 579 | 113.178 | 149.741 | 185.771 | 331 | 745 | 0 |
| 18 | Fastify on deno | 578 | 111.882 | 150.101 | 187.575 | 349 | 747 | 0 |
| 19 | Deno.serve (baseline) on deno | 570 | 114.894 | 153.133 | 187.413 | 296 | 747 | 0 |
| 20 | Express 5 on deno | 565 | 115.302 | 151.638 | 190.107 | 351 | 748 | 0 |
| 21 | uWebSockets.js on node | 550 | 114.362 | 125.662 | 151.907 | 169 | 412 | 0 |
| 22 | HyperExpress on node | 549 | 114.67 | 123.469 | 145.847 | 192 | 412 | 0 |
| 23 | Elysia on node | 546 | 115.92 | 123.749 | 156.487 | 224 | 410 | 0 |
| 24 | NestJS (Express) on deno | 538 | 119.931 | 158.484 | 204.602 | 408 | 748 | 0 |
| 25 | node:http (baseline) on deno | 512 | 128.596 | 165.608 | 206.911 | 327 | 747 | 0 |
| 26 | Fastify on node | 509 | 125.17 | 139.144 | 161.66 | 179 | 413 | 0 |
| 27 | NestJS (Fastify) on node | 480 | 132.577 | 141.748 | 160.409 | 203 | 416 | 0 |
| 28 | Hapi on node | 476 | 133.634 | 140.646 | 170.724 | 200 | 414 | 0 |
| 29 | Koa on node | 475 | 133.088 | 142.793 | 168.86 | 183 | 412 | 0 |
| 30 | NestJS (Express) on node | 474 | 134.122 | 144.28 | 159.864 | 256 | 412 | 0 |
| 31 | Hono on node | 470 | 133.933 | 144.618 | 177.261 | 182 | 413 | 0 |
| 32 | Express 5 on node | 458 | 138.255 | 150.096 | 174.114 | 181 | 414 | 0 |
| 33 | h3 on node | 455 | 138.585 | 151.931 | 182.147 | 178 | 413 | 0 |
| 34 | node:http (baseline) on node | 384 | 167.287 | 176.03 | 212.824 | 175 | 406 | 0 |
Mixed traffic at fixed rate (k6)
Bar = p99 latency at a fixed arrival rate (shorter is better). Right column shows achieved RPS.
Table view
| # | Combo | RPS | p50 ms | p90 ms | p99 ms | RSS MB | CPU % | Errors |
|---|---|---|---|---|---|---|---|---|
| 1 | node:http (baseline) on bun | 1,500 | 0.329 | 2.528 | 6.931 | 156 | 58 | 0 |
| 2 | h3 on bun | 1,500 | 0.339 | 2.563 | 6.946 | 149 | 58 | 0 |
| 3 | Bun.serve (baseline) on bun | 1,500 | 0.335 | 2.609 | 6.961 | 136 | 58 | 0 |
| 4 | Fastify on bun | 1,500 | 0.336 | 2.542 | 6.972 | 181 | 59 | 0 |
| 5 | Hono on bun | 1,500 | 0.339 | 2.619 | 6.973 | 138 | 59 | 0 |
| 6 | Elysia on bun | 1,500 | 0.335 | 2.567 | 6.975 | 155 | 58 | 0 |
| 7 | Express 5 on bun | 1,500 | 0.347 | 2.596 | 6.996 | 169 | 60 | 0 |
| 8 | Koa on bun | 1,500 | 0.345 | 2.602 | 7.009 | 204 | 59 | 0 |
| 9 | NestJS (Express) on bun | 1,500 | 0.354 | 2.566 | 7.026 | 231 | 61 | 0 |
| 10 | NestJS (Fastify) on bun | 1,500 | 0.348 | 2.579 | 7.034 | 218 | 60 | 0 |
| 11 | Hapi on bun | 1,500 | 0.348 | 2.678 | 7.045 | 197 | 61 | 0 |
| 12 | uWebSockets.js on node | 1,500 | 0.344 | 2.579 | 8.364 | 165 | 70 | 0 |
| 13 | Fastify on node | 1,500 | 0.354 | 2.655 | 8.377 | 175 | 72 | 0 |
| 14 | h3 on node | 1,500 | 0.358 | 2.582 | 8.378 | 177 | 72 | 0 |
| 15 | HyperExpress on node | 1,500 | 0.349 | 2.543 | 8.397 | 168 | 71 | 0 |
| 16 | Elysia on node | 1,500 | 0.361 | 2.635 | 8.403 | 204 | 72 | 0 |
| 17 | Hono on node | 1,500 | 0.356 | 2.578 | 8.41 | 183 | 73 | 0 |
| 18 | NestJS (Fastify) on node | 1,500 | 0.363 | 2.622 | 8.411 | 266 | 73 | 0 |
| 19 | Express 5 on node | 1,500 | 0.368 | 2.647 | 8.427 | 178 | 74 | 0 |
| 20 | Koa on node | 1,500 | 0.361 | 2.564 | 8.439 | 195 | 74 | 0 |
| 21 | Hapi on node | 1,500 | 0.371 | 2.569 | 8.44 | 198 | 74 | 0 |
| 22 | NestJS (Express) on node | 1,500 | 0.379 | 2.589 | 8.469 | 261 | 75 | 0 |
| 23 | node:http (baseline) on node | 1,500 | 0.347 | 2.642 | 8.552 | 179 | 73 | 0 |
| 24 | Hono on deno | 1,500 | 0.359 | 2.593 | 8.971 | 183 | 77 | 0 |
| 25 | Deno.serve (baseline) on deno | 1,500 | 0.353 | 2.596 | 8.984 | 178 | 76 | 0 |
| 26 | h3 on deno | 1,500 | 0.364 | 2.629 | 8.993 | 178 | 77 | 0 |
| 27 | Elysia on deno | 1,500 | 0.363 | 2.652 | 8.999 | 171 | 78 | 0 |
| 28 | node:http (baseline) on deno | 1,500 | 0.361 | 2.76 | 8.999 | 187 | 79 | 0 |
| 29 | Fastify on deno | 1,500 | 0.364 | 2.594 | 9.012 | 187 | 77 | 0 |
| 30 | Express 5 on deno | 1,500 | 0.378 | 2.662 | 9.033 | 195 | 80 | 0 |
| 31 | NestJS (Fastify) on deno | 1,500 | 0.378 | 2.645 | 9.048 | 249 | 81 | 0 |
| 32 | Koa on deno | 1,500 | 0.377 | 2.681 | 9.063 | 235 | 81 | 0 |
| 33 | NestJS (Express) on deno | 1,500 | 0.393 | 2.72 | 9.1 | 230 | 82 | 0 |
| 34 | Hapi on deno | 1,500 | 0.387 | 2.721 | 9.109 | 244 | 83 | 0 |
Not available / failed
- uws@bun: process exited early: at /Users/ninggiangboy/Develops/side-project/benchmark/dist/apps/uws/main.js:57:42 | | Bun v1.4.3 (macOS arm64)
- hyper-express@bun: process exited early: at <anonymous> (/Users/ninggiangboy/Develops/side-project/benchmark/node_modules/hyper-express/index.js:4:7) | | Bun v1.4.3 (macOS