Developers who use Express every day often cannot say exactly what happens between a request arriving and a response leaving. Ahmed Sozzer’s first-person account, published on DEV Community (originally at amsozzer.com, displayed with a September 23 date in 2026), describes how he tried to close that gap by building PlusWeb, an Express-style web framework in C++. The short answer is that writing the machinery made middleware order, next(), and routing legible to him, while the benchmark numbers he reports turned out to be a side effect of the exercise rather than its purpose.
Why the project started: middleware that worked but did not make sense
Sozzer’s stated goal was to understand Express, especially middleware chaining. He reports that a first attempt in JavaScript sat at too similar an abstraction level to teach him much, so he restarted in C++, where the mechanics of dispatch, memory, and I/O had to be spelled out. The lesson he draws is that a reimplementation forces you to answer questions that using a framework lets you skip: who calls the next handler, what happens when a handler never calls next(), and where an error handler is found when something throws.
As an Amazon Associate I earn from qualifying purchases.
What the author says Express does, and how PlusWeb differs
The central difference the article describes is in routing. In the author’s characterization, Express checks its layer stack in registration order, so each incoming request is matched against layers one after another. PlusWeb instead uses a segment trie keyed around the HTTP method and the URL path. Lookup follows the path’s segments through the trie, so the cost depends on how many segments a path has rather than on how many routes the application registered.
That is the author’s description of his own implementation, not an independent analysis of Express internals. It is still a useful mental model: if you can picture a list being scanned versus a tree being walked, the question “why does order of app.use and app.get matter?” becomes easier to reason about.
#1 Best Overall
Reading the benchmarks correctly
The article reports throughput for PlusWeb and Express at three route counts. The setup is described as one pinned core, with identical handlers and payloads. The figures below are the author’s measurements, not third-party results, and they were not independently reproduced for this article.
| Registered routes | PlusWeb (requests/sec) | Express (requests/sec) | Ratio reported by author |
|---|---|---|---|
| 5 | 91,950 | 19,236 | 4.8× |
| 1,000 | 90,085 | 5,639 | 16× |
| 10,000 | 89,636 | 355 | 253× |
The author calls the five-route row the honest one for a typical small application and advises quoting 4.8× if you need a single figure. The larger multiples mostly reflect Express’s falling throughput as the route table grows; PlusWeb’s figures stay roughly flat across the three rows. Presenting the 16× or 253× rows on their own would suggest a general verdict about C++ against Express, and the article does not support that. It is a measurement of one router under one setup.
Replacing the hand-built I/O layer
The first infrastructure changes were about correctness rather than speed. The author describes replacing a blocking, hand-built loop with libuv, and replacing his own HTTP parser with llhttp. He says the custom parser mishandled framing cases that llhttp handles, so the switch improved parsing correctness as well as code quality.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →The profiling lesson: the bottleneck was not where he expected
Later profiling turned up a response-code map that was rebuilt on every response. Moving it to shared static storage removed repeated allocations and insertions. The author reports the following changes, from a comparison he says ran each version 200,000 times with the same compiler flags and produced byte-identical output.
| Measurement | Before | After | Change reported |
|---|---|---|---|
| HttpResponse construction | 3,390 ns | 10.0 ns | 339× |
| Full response path | 3,400 ns | 255 ns | 13× |
The more instructive result is the profile breakdown. Most time in the author’s setup was spent in libc send and recv stubs, not in the code he had been tuning.
| Component (author’s profile) | Share of profiled time |
|---|---|
libc syscall stubs (send/recv) |
about 71% |
| llhttp internals | 3.0% |
| Message completion | 1.8% |
| Response serialization | 0.5% |
| Router lookup (after optimization) | 0.5% |
These shares describe one machine and one application. They are not a portable expectation for other hardware or workloads. The practical takeaway is the method rather than the numbers: profile the real hot path before deciding that the most visible subsystem, here the router, is the problem.
When rebuilding a framework is worth it
- Worth it: you need to explain how request dispatch, error propagation, or handler ordering works, and reading the framework’s source has not made it click.
- Worth it: you want to test your understanding by predicting behavior before running the code.
- Probably a distraction: your goal is to ship a production service. The article does not establish broad production suitability, feature parity with Express, or behavior across arbitrary applications.
- Probably a distraction: you are rebuilding the transport layer, parser, and event loop when the question you have is about middleware. The author’s own experience suggests that reimplementing everything can move attention away from the concept you set out to learn.
Where to look if you want to explore
The article states that PlusWeb is published on GitHub under the MIT license and that a playground runs its router compiled to WebAssembly, which lets you test route matching in a browser. The article does not confirm the repository’s current status beyond that statement, so check the repository’s activity before depending on it.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
In the author’s words, the point was never the benchmarks: “That was the point. The benchmarks are a side effect, and a slightly misleading one, because they make the project look like it was about speed.” The payoff he describes is the ability to explain the stack: “I can tell you what Express does when a request arrives, because I have written the thing that does it.”
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

