Every number Moro publishes comes from a run you can repeat. Same app, same load generator, three engines. This page is the methodology, the raw output, and the command to reproduce it on your own hardware.
A hello-world JSON route scaffolded with init --fast, measured with wrk. The only difference between bars is the engine config line.
August 2026 run on the hardware described below.
➜ wrk -c100 -d40s http://127.0.0.1:3000/ 100 connections · 40 seconds · no pipelining app: stock CLI scaffold · production mode Latency avg 0.90ms Latency p99 1.90ms Requests/sec: 108,687
Every row from the August 2026 results file: MoroJS configurations, other frameworks, and raw-server baselines, measured in one session on one machine.
| Server | Req/s | Req/s pipelined ×10 | Latency avg | p99 | RSS under load |
|---|---|---|---|---|---|
| @morojs/engineraw | 111,325 | 779,935 | 0.9 ms | 1.8 ms | 47 MB |
| MoroJS + @morojs/engine · clustered | 109,144 | 741,719 | 0.9 ms | 1.7 ms | 1582 MB |
| MoroJS + @morojs/engine · single process | 108,687 | 688,980 | 0.9 ms | 1.9 ms | 65 MB |
| uWebSockets.jsraw | 107,935 | 656,155 | 0.9 ms | 1.7 ms | 43 MB |
| MoroJS + uWebSockets.js · adapter | 103,061 | 527,074 | 0.9 ms | 1.9 ms | 73 MB |
| Bun.serveraw | 99,613 | 24,970 | 1.0 ms | 3.0 ms | 29 MB |
| Elysia (Bun) | 98,139 | 23,916 | 1.0 ms | 2.5 ms | 41 MB |
| node:httpraw | 71,437 | 116,116 | 1.4 ms | 5.0 ms | 136 MB |
| MoroJS · node engine, single thread | 71,080 | 124,535 | 1.4 ms | 2.6 ms | 140 MB |
| Fastify | 68,880 | 109,492 | 1.4 ms | 4.2 ms | 139 MB |
| Elysia (Node adapter) | 65,034 | 112,427 | 1.5 ms | 2.7 ms | 207 MB |
| Hono (Node) | 64,758 | 107,757 | 1.5 ms | 2.9 ms | 200 MB |
| Koa (Node) | 59,697 | 88,606 | 1.7 ms | 4.8 ms | 204 MB |
| Express (Node) | 45,976 | 65,988 | 2.2 ms | 4.4 ms | 209 MB |
Baselines are raw servers with no framework; they're the ceiling, not a competitor. Bun rows use Bun's own runtime. The pipelined ×10 column is a microbench that favors servers that batch aggressively. Read it as a ceiling, not a forecast.
Benchmarks are only useful if the setup is boring and public. Here's ours.
Apple M-series, darwin/arm64, node v24.11.0, mains power, no other foreground workloads. One machine for both app and load generator, which flatters nobody.
wrk, 100 connections, 40 seconds. Pipelined ×10 numbers come from a separate microbench and are always labeled as such.
The stock CLI scaffold, one JSON route, no logging, production mode. No hand-tuned special-case server.
That you'll see these numbers behind your load balancer, or that hello-world predicts your workload. It measures framework overhead, nothing more.
Two commands and wrk. If your ordering comes out different, file an issue . We mean it.
$ npx @morojs/cli init bench-app --fast$ cd bench-app && NODE_ENV=production npm start$ wrk -c100 -d40s http://127.0.0.1:3000/