Every router benchmark has a winner.
Conveniently, it is often the router favored by the person who ran the benchmark.
That is not always dishonest. Sometimes the benchmark is just too narrow, too flattering, or too cute to say anything useful about a real app.
Node.js routers are a perfect example.
You can build a chart where Hono looks unbeatable.
You can build one where trie routers look like the only serious option.
And you can build one where some other router suddenly jumps to the top.
Which is why I wanted to benchmark routers in a way that is a bit less flattering and a bit more annoying.
I tested:
- Express
- Fastify's
find-my-way rou3- Hono
@prostojs/router
But before the results, here is the only part that actually matters: what exactly was measured.
The raw benchmark code lives here: router-benchmark.
Worth noting: rou3 is not just some random router on a comparison chart. It powers H3 routing, Nitro is built around H3, and Nuxt server routes run on Nitro. So the chain is basically rou3 → H3 → Nitro → Nuxt.
The one benchmark rule that actually matters
Router benchmarks are often misleading because they do not measure the same work.
Some routers extract params eagerly. Others return internal structures that still need to be decoded. If the benchmark stops before that last step, the numbers look cleaner than reality — great for slides, less great for truth.

So my benchmark forces full lookup work:
- match the route
- extract params
- handle static, parametric, wildcard, and miss cases
- test short, long, and mixed route sets
A much fairer comparison, because real applications need the params, not just the match.
I also did not stop at one route table. The benchmark covers:
- short routes
- long enterprise-style routes
- mixed route sets
- a scaling run from 22 to 200 routes
Because "fastest router" on 22 shallow routes is a very different question from "what happens when the route table starts looking like a real backend?"
Hono is really fast — until it is not
Let’s get the obvious part out of the way: Hono is fast.
In the 22-route benchmark, Hono’s RegExpRouter led both the short-route and mixed-route variants. If your app has a small route table with lots of shallow paths, that result is real and worth respecting.
Here is the small-route snapshot: shallow routes, 22 total, full route match plus param extraction, 200k operations per test, averaged over 2 runs.
One glance: Hono looks excellent when the route set is small and shallow. That part of the "Hono is fast" story is absolutely real.
If the article ended here, the conclusion would be simple:
"Hono is the fastest router, congratulations everyone, time for lunch."
But that is exactly the kind of conclusion that makes router benchmarks misleading. So I kept pushing.
Deep routes change the leaders
The long-route benchmark looks more like the APIs I actually work with:
- shared
/api/v1/...prefixes - several nested segments
- one to four params
- realistic SaaS-style depth
At 22 routes, @prostojs/router took the lead:
-
@prostojs/router: about9020 op/ms - Hono
RegExpRouter: about8250 op/ms -
rou3: about7157 op/ms -
find-my-way: about6283 op/ms
Already a different picture from the "Hono wins everything" headline.
Not all routers scale the same
The most revealing result was not the 22-route snapshot. It was the scale test.
Once the route table grows from 22 to 50 to 100 to 200 routes, the question shifts from "who wins this chart?" to "what happens when the app stops being a toy?"
At higher route counts, Hono's RegExpRouter stopped compiling for the deep-route case and fell back to TrieRouter — much slower in that workload.
That does not make Hono bad. It means its headline speed is workload-sensitive, which matters when people treat "the fastest router" as a law of physics.
There is another outcome here that deserves attention: find-my-way and rou3 scale really well. If your route table is going to grow large and predictable scaling is a top priority, the trie routers look excellent. A real advantage, not a footnote.
The honest summary is not "regex good" or "trie good." It is closer to:
- Hono looks amazing in the flattering small-route case
-
@prostojs/routeris especially strong on deep and parametric routes -
find-my-wayandrou3stay impressively stable as route count grows
This next chart is the most important one in the article: deep enterprise-style routes, route counts growing from 22 to 200, full lookup work, 500k operations per point, averaged over 5 runs.

This chart matters more than any braggy headline.
It also highlights what makes @prostojs/router interesting: strong on deep and parametric routes, without sacrificing features to get there.
Router benchmarks are (mostly) sport
Here is the conclusion I came to after benchmarking full HTTP frameworks, not just routers.
Router benchmarks are useful — they reveal tradeoffs, expose scaling cliffs, and punish bad assumptions.
But they are overrated, because they isolate a cost that gets diluted fast in a real app.
The moment you add HTTP request handling, header and cookie parsing, body parsing, auth checks, validation, or database work — the router becomes a small part of total request cost.
That is what I saw in the related Wooks and Moost benchmarks: big router-level gaps shrink at framework level, then shrink again once real work enters the picture.
Wooks has a dedicated router benchmark analysis here:
wooks.moost.org/benchmarks/router.html
If someone picks a router entirely by a benchmark headline, they are probably optimizing the wrong thing.
This next chart moves one level up — from pure routing to full HTTP framework overhead. It comes from the Wooks benchmark using a realistic SaaS-style route mix with auth, cookies, headers, body parsing, and actual handlers.

Already smaller gaps than at the pure router level.
And this final chart adds real I/O: each authenticated request performs a local Redis operation — the kind of work that quickly dominates any routing difference in production.

Add real work, and the gap shrinks again.
Choose features, not speed
Once a router is fast enough, speed stops being the deciding factor.
What matters more:
- correctness on tricky and encoded URLs
- the route patterns you actually need
- predictable params and wildcards
- stable scaling without weird cliffs
- solid TypeScript ergonomics
@prostojs/router sits in an interesting spot: top-tier performance while offering features many fast routers skip — regex-constrained params, multiple wildcards, optional params and wildcards, path builders, and correct URL handling.
That is also why this benchmark became the starting point for a bigger stack. I used @prostojs/router as the foundation for Wooks, because once routing is solved well enough, the next problem is far more interesting:
Where does request context actually live?
Not in benchmark charts. In real code — auth state, cookies, parsed bodies, tenant resolution, request IDs, and all the other things that get shoved into req, threaded through helpers, or quietly hidden in middleware.
That is what I want to dig into next.
Read next: The request context problem — Why req became a junk drawer and what happens when you stop treating it like one.


Top comments (0)