Skip to content

frameworks/node: add benchmark implementation - #1202

Merged
MDA2AV merged 2 commits into
MDA2AV:mainfrom
nigrosimone:add-node
Aug 18, 2026
Merged

frameworks/node: add benchmark implementation#1202
MDA2AV merged 2 commits into
MDA2AV:mainfrom
nigrosimone:add-node

Conversation

@nigrosimone

Copy link
Copy Markdown
Contributor

Node was on the board only through frameworks (express, fastify, koa, nestjs, node-h3, hono-node), with no bare node:http line to read them against. bun, deno and go-stdlib already have one.

One file, no dependencies: http.createServer, routing by string comparison on req.url, query parsed by hand, and zlib.gzipSync on /json because node:http negotiates nothing.

node:cluster forks one worker per core, but each worker binds 8080 with reusePort, so the kernel spreads the accepts the way bun and deno do, not the cluster round robin.

Profiles are the same six as bun, deno and go-stdlib. Checked with the image on 4 cpus: 4 workers, 4 LISTEN sockets on 8080, and every endpoint the profiles use.

@nigrosimone
nigrosimone marked this pull request as ready for review August 18, 2026 06:22
@MDA2AV

MDA2AV commented Aug 18, 2026

Copy link
Copy Markdown
Owner

/benchmark --save

@github-actions

Copy link
Copy Markdown
Contributor

👋 Benchmark request received. A collaborator will review and approve the run.

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Results

Framework: node | Test: all tests

Test Conn RPS CPU Mem Δ RPS Δ Mem
baseline 512 907,802 6679.8% 1.5GiB ~0% ~0%
baseline 4096 892,087 6553.9% 1.6GiB ~0% ~0%
pipelined 512 1,848,457 6669.2% 2.3GiB ~0% ~0%
pipelined 4096 1,837,282 6553.1% 2.5GiB ~0% ~0%
limited-conn 512 747,342 6187.4% 5.3GiB ~0% ~0%
limited-conn 4096 768,440 6415.9% 5.4GiB ~0% ~0%
json 4096 713,493 6393.6% 5.0GiB ~0% ~0%
json-comp 512 281,475 5817.4% 8.9GiB ~0% ~0%
json-comp 4096 289,309 6307.9% 9.0GiB ~0% ~0%
json-comp 16384 285,229 6180.5% 9.5GiB ~0% ~0%
upload 32 2,058 2462.3% 5.3GiB ~0% ~0%
upload 256 2,156 5931.9% 5.6GiB ~0% ~0%
Full log
[info] server ready

[run 1/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     32 (0/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 4
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   15.48ms   8.97ms   37.30ms   78.90ms   123.00ms

  10292 requests in 5.00s, 10292 responses
  Throughput: 2.06K req/s
  Bandwidth:  340.07KB/s
  Status codes: 2xx=10292, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 10292 / 10292 responses (100.0%)
  Reconnects: 2056
  Per-template: 2558,2551,2596,2587
  Per-template-ok: 2558,2551,2596,2587
[info] CPU 2462.3% | Mem 5.3GiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     32 (0/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 4
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   15.56ms   8.88ms   37.20ms   83.50ms   130.60ms

  10266 requests in 5.00s, 10266 responses
  Throughput: 2.05K req/s
  Bandwidth:  339.22KB/s
  Status codes: 2xx=10266, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 10266 / 10266 responses (100.0%)
  Reconnects: 2055
  Per-template: 2562,2554,2564,2586
  Per-template-ok: 2562,2554,2564,2586
[info] CPU 2654.0% | Mem 5.4GiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     32 (0/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 4
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   15.60ms   8.77ms   37.90ms   91.30ms   125.60ms

  10234 requests in 5.00s, 10234 responses
  Throughput: 2.04K req/s
  Bandwidth:  338.17KB/s
  Status codes: 2xx=10234, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 10234 / 10234 responses (100.0%)
  Reconnects: 2047
  Per-template: 2553,2544,2558,2579
  Per-template-ok: 2553,2544,2558,2579
[info] CPU 2504.0% | Mem 5.4GiB

=== Best: 2058 req/s (CPU: 2462.3%, Mem: 5.3GiB) ===
[info] input BW: 16.32GB/s (avg template: 8516680 bytes)
[info] saved results/upload/32/node.json
httparena-bench-node
httparena-bench-node

==============================================
=== node / upload / 256c (tool=gcannon) ===
==============================================
[info] waiting for server...
[info] server ready

[run 1/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     256 (4/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 4
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   115.53ms   63.00ms   306.60ms   656.70ms   940.00ms

  10785 requests in 5.00s, 10783 responses
  Throughput: 2.15K req/s
  Bandwidth:  356.28KB/s
  Status codes: 2xx=10783, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 10783 / 10783 responses (100.0%)
  Reconnects: 2115
  Per-template: 2459,2808,2899,2617
  Per-template-ok: 2459,2808,2899,2617
[info] CPU 5931.9% | Mem 5.6GiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     256 (4/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 4
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   116.72ms   63.10ms   305.30ms   709.00ms   975.30ms

  10724 requests in 5.00s, 10723 responses
  Throughput: 2.14K req/s
  Bandwidth:  354.31KB/s
  Status codes: 2xx=10723, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 10722 / 10723 responses (100.0%)
  Reconnects: 2106
  Per-template: 2414,2786,2905,2617
  Per-template-ok: 2414,2786,2905,2617
[info] CPU 6134.0% | Mem 5.7GiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     256 (4/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 4
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   116.09ms   61.10ms   300.80ms   730.00ms    1.06s

  10771 requests in 5.00s, 10771 responses
  Throughput: 2.15K req/s
  Bandwidth:  355.91KB/s
  Status codes: 2xx=10771, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 10767 / 10771 responses (100.0%)
  Reconnects: 2110
  Per-template: 2449,2791,2898,2629
  Per-template-ok: 2449,2791,2898,2629
[info] CPU 5941.2% | Mem 5.7GiB

=== Best: 2156 req/s (CPU: 5931.9%, Mem: 5.6GiB) ===
[info] input BW: 17.10GB/s (avg template: 8516680 bytes)
[info] saved results/upload/256/node.json
httparena-bench-node
httparena-bench-node
[info] skip: node does not subscribe to api-4
[info] skip: node does not subscribe to api-16
[info] skip: node does not subscribe to static
[info] skip: node does not subscribe to static-tls
[info] skip: node does not subscribe to async-db
[info] skip: node does not subscribe to crud
[info] skip: node does not subscribe to fortunes
[info] skip: node does not subscribe to baseline-h2
[info] skip: node does not subscribe to static-h2
[info] skip: node does not subscribe to baseline-h2c
[info] skip: node does not subscribe to json-h2c
[info] skip: node does not subscribe to baseline-h3
[info] skip: node does not subscribe to static-h3
[info] skip: node does not subscribe to gateway-64
[info] skip: node does not subscribe to gateway-h3
[info] skip: node does not subscribe to production-stack
[info] skip: node does not subscribe to unary-grpc
[info] skip: node does not subscribe to unary-grpc-tls
[info] skip: node does not subscribe to stream-grpc
[info] skip: node does not subscribe to stream-grpc-tls
[info] skip: node does not subscribe to echo-ws
[info] skip: node does not subscribe to echo-ws-pipeline
[info] skip: node does not subscribe to echo-ws-limited
[info] rebuilding site/data/*.json
[purged stale] zix-grpc.json (zix-grpc)
[purged stale] zix-ws.json (zix-ws)
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/frameworks.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/results/node.json - 12 new, 12 total
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/current.json
[info] done
[info] restoring loopback MTU to 65536

@MDA2AV
MDA2AV merged commit 4810c11 into MDA2AV:main Aug 18, 2026
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.

2 participants