Skip to content

perf: remove per-request async overhead in router dispatch - #354

Open
nigrosimone wants to merge 1 commit into
dimdenGD:mainfrom
nigrosimone:perf-route-2
Open

perf: remove per-request async overhead in router dispatch#354
nigrosimone wants to merge 1 commit into
dimdenGD:mainfrom
nigrosimone:perf-route-2

Conversation

@nigrosimone

@nigrosimone nigrosimone commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
  • start req.routeCount at 1 so the first route of a request takes the synchronous _preprocessRequest path: 0 % 300 === 0 forced an await on every single request, deferring the whole handler chain to a microtask
  • make next() a plain function instead of async, removing an unconsumed promise allocation on every middleware/handler step; the nested router branch now chains with .then() instead of await

middlewares-100 (+26%) e nested-routers (+21%)

MASTER (LATEST COMMIT)

Test Express req/sec uExpress req/sec Express throughput uExpress throughput uExpress speedup
engines/art 8.70k 19.49k 3.82 MB/sec 8.57 MB/sec 2.24x
middlewares/body-urlencoded 13.78k 48.40k 2.14 MB/sec 7.57 MB/sec 3.54x
middlewares/compression-file 7.17k 9.34k 3.27 MB/sec 4.27 MB/sec 1.31x
middlewares/express-static 3.68k 5.04k 901.12 MB/sec 1.20 GB/sec 1.36x
routing/hello-world 18.65k 116.39k 3.09 MB/sec 19.42 MB/sec 6.28x
routing/middlewares-100 15.07k 21.03k 2.36 MB/sec 3.31 MB/sec 1.40x
routing/nested-routers 18.84k 91.79k 3.02 MB/sec 14.79 MB/sec 4.90x
routing/routes-1000 4.27k 78.28k 683.46 KB/sec 12.32 MB/sec 18.46x
streaming/readable-hash-4mb 18.60k 105.96k 6.88 MB/sec 39.31 MB/sec 5.71x
streaming/writable-no-content-length 788.32 1.07k 3.85 GB/sec 5.22 GB/sec 1.36x
streaming/writable-with-content-length 1.07k 1.06k 5.25 GB/sec 5.19 GB/sec 0.99x

PR

Test Express req/sec uExpress req/sec Express throughput uExpress throughput uExpress speedup
engines/art 5.05k 11.82k 2.22 MB/sec 5.20 MB/sec 2.34x
middlewares/body-urlencoded 8.44k 33.62k 1.31 MB/sec 5.26 MB/sec 4.02x
middlewares/compression-file 4.69k 7.01k 2.14 MB/sec 3.21 MB/sec 1.50x
middlewares/express-static 2.54k 4.29k 622.61 MB/sec 1.02 GB/sec 1.68x
routing/hello-world 11.66k 82.80k 1.93 MB/sec 13.82 MB/sec 7.16x
routing/middlewares-100 9.77k 17.23k 1.53 MB/sec 2.71 MB/sec 1.77x
routing/nested-routers 11.30k 66.63k 1.81 MB/sec 10.74 MB/sec 5.93x
routing/routes-1000 3.83k 63.43k 613.46 KB/sec 9.98 MB/sec 16.66x
streaming/readable-hash-4mb 11.62k 73.35k 4.30 MB/sec 27.21 MB/sec 6.33x
streaming/writable-no-content-length 633.40 791.69 3.09 GB/sec 3.87 GB/sec 1.25x
streaming/writable-with-content-length 703.81 821.17 3.44 GB/sec 4.01 GB/sec 1.17x

- start req.routeCount at 1 so the first route of a request takes the
  synchronous _preprocessRequest path: 0 % 300 === 0 forced an await on
  every single request, deferring the whole handler chain to a microtask
- make next() a plain function instead of async, removing an unconsumed
  promise allocation on every middleware/handler step; the nested router
  branch now chains with .then() instead of await
@nigrosimone
nigrosimone marked this pull request as ready for review July 30, 2026 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant