Skip to content

Conversation

ronag
Copy link
Member

@ronag ronag commented Sep 3, 2025

PRE:

┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬──────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg      │ Stdev    │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼──────────┼─────────┤
│ Req/Sec   │ 88,319  │ 88,319  │ 95,679  │ 96,447  │ 93,885.1 │ 2,779.85 │ 88,303  │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼──────────┼─────────┤
│ Bytes/Sec │ 10.8 MB │ 10.8 MB │ 11.7 MB │ 11.8 MB │ 11.5 MB  │ 339 kB   │ 10.8 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴──────────┴─────────┘

POST:

┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec   │ 93,823  │ 93,823  │ 100,287 │ 101,119 │ 99,680  │ 1,967.7 │ 93,817  │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 11.5 MB │ 11.5 MB │ 12.2 MB │ 12.3 MB │ 12.2 MB │ 238 kB  │ 11.4 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/http
  • @nodejs/net

@ronag ronag added the http Issues or PRs related to the http subsystem. label Sep 3, 2025
@nodejs-github-bot nodejs-github-bot added the needs-ci PRs that need a full CI run. label Sep 3, 2025
@ronag ronag requested review from RafaelGSS and mcollina September 3, 2025 15:45
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina added the request-ci Add this label to start a Jenkins CI on a PR. label Sep 3, 2025
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Sep 3, 2025
@nodejs-github-bot

This comment was marked as outdated.

@RafaelGSS RafaelGSS added the performance Issues and PRs related to the performance of Node.js. label Sep 3, 2025
@ronag ronag marked this pull request as ready for review September 3, 2025 20:21
@ronag ronag requested a review from mcollina September 3, 2025 20:22
@ronag ronag added the request-ci Add this label to start a Jenkins CI on a PR. label Sep 3, 2025
@ronag ronag force-pushed the faster-dump branch 4 times, most recently from d3ff5f6 to e86d740 Compare September 3, 2025 20:27
@ronag ronag added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Sep 3, 2025
@github-actions github-actions bot added request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Sep 3, 2025
Copy link
Contributor

github-actions bot commented Sep 3, 2025

Failed to start CI
   ⚠  Commits were pushed since the last approving review:
   ⚠  - http: optimize IncomingMessage._dump
   ✘  Refusing to run CI on potentially unsafe PR
https://github.com/nodejs/node/actions/runs/17445334596

@ronag ronag force-pushed the faster-dump branch 5 times, most recently from 197ba2c to 60e12ac Compare September 3, 2025 21:06
@ronag
Copy link
Member Author

ronag commented Sep 4, 2025

I don't know how to deal with the testing of this. Optimally I would like to run all http tests with and without the option.

@ronag
Copy link
Member Author

ronag commented Sep 4, 2025

@ronag
Copy link
Member Author

ronag commented Sep 4, 2025

@RafaelGSS any idea why benchmark ci failed?

@Flarna
Copy link
Member

Flarna commented Sep 4, 2025

Why should we run all HTTP tests with this option on and off? What makes this option so special to run that a high number of tests?

@ronag
Copy link
Member Author

ronag commented Sep 4, 2025

Why should we run all HTTP tests with this option on and off? What makes this option so special to run that a high number of tests?

I think this is one of those changes that can cause various regression.

@RafaelGSS
Copy link
Member

@ronang Benchmark CI https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/1728/

You forgot to include the commit SHA.

@RafaelGSS RafaelGSS closed this Sep 4, 2025
@ronag
Copy link
Member Author

ronag commented Sep 4, 2025

@RafaelGSS why did you close?

@RafaelGSS RafaelGSS reopened this Sep 4, 2025
@RafaelGSS
Copy link
Member

I was a mistake, sorry @ronag

This comment was marked as outdated.

doc/api/http.md Outdated
@@ -3632,6 +3635,10 @@ changes:
* `rejectNonStandardBodyWrites` {boolean} If set to `true`, an error is thrown
when writing to an HTTP response which does not have a body.
**Default:** `false`.
* `dumpGETBody` {boolean} If set to `true`, request body for `HEAD` and `GET`
requests will be immediatly dumped and the `end` and `close` events for
`IncomingMessage` will be emitted before the server emits `'request'`. This
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that this is behind an option but I find it odd. It breaks the invariant where 'end' / 'close' are always emitted.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a valid point. I don't think it's anywhere documented that it must emit the life cycle events. Though it is indeed breaking. It is totally valid from the streams api since you can receive an already closed stream. It will work with stream.finished and stream.pipeline.

@ronag ronag force-pushed the faster-dump branch 2 times, most recently from d9d8fbc to fc3f493 Compare September 4, 2025 20:05
@ronag
Copy link
Member Author

ronag commented Sep 4, 2025

@mcollina @RafaelGSS benchmark CI is not meaningful, I added my own autocannon benchmark #59747 (comment)

const http = require('http');

http.createServer((req, res) => {
  res.end();
}).listen(9000);
npx autocannon http://localhost:9000

@ronag ronag added the semver-major PRs that contain breaking changes and should be released in the next major version. label Sep 4, 2025
@mcollina
Copy link
Member

mcollina commented Sep 4, 2025

Can we implement so that if there is someone watching for ‘end’ or ‘close’, it follows the usual path, while if they are not, we can avoid them?

Alternatively, we could have _dump actually emit them.

@ronag
Copy link
Member Author

ronag commented Sep 4, 2025

With fastify:

nxt-23.0$ npx autocannon http://localhost:9000/
Running 10s test @ http://localhost:9000/
10 connections


┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬────────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max    │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼────────┤
│ Latency │ 0 ms │ 0 ms │ 0 ms  │ 0 ms │ 0.03 ms │ 0.84 ms │ 137 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬───────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg      │ Stdev     │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼───────────┼─────────┤
│ Req/Sec   │ 23,711  │ 23,711  │ 50,911  │ 79,487  │ 54,421.6 │ 22,087.53 │ 23,701  │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼───────────┼─────────┤
│ Bytes/Sec │ 4.32 MB │ 4.32 MB │ 9.27 MB │ 14.5 MB │ 9.9 MB   │ 4.02 MB   │ 4.31 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴───────────┴─────────┘

Req/Bytes counts sampled once per second.
# of samples: 10

544k requests in 10.04s, 99 MB read
nxt-23.0$ npx autocannon http://localhost:9000/
Running 10s test @ http://localhost:9000/
10 connections


┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬───────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max   │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼───────┤
│ Latency │ 0 ms │ 0 ms │ 0 ms  │ 0 ms │ 0.01 ms │ 0.27 ms │ 76 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴───────┘
┌───────────┬─────────┬─────────┬────────┬─────────┬─────────┬──────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%    │ 97.5%   │ Avg     │ Stdev    │ Min     │
├───────────┼─────────┼─────────┼────────┼─────────┼─────────┼──────────┼─────────┤
│ Req/Sec   │ 68,287  │ 68,287  │ 82,175 │ 84,223  │ 81,056  │ 4,446.14 │ 68,272  │
├───────────┼─────────┼─────────┼────────┼─────────┼─────────┼──────────┼─────────┤
│ Bytes/Sec │ 12.4 MB │ 12.4 MB │ 15 MB  │ 15.3 MB │ 14.8 MB │ 809 kB   │ 12.4 MB │
└───────────┴─────────┴─────────┴────────┴─────────┴─────────┴──────────┴─────────┘

Req/Bytes counts sampled once per second.
# of samples: 10

811k requests in 10.02s, 148 MB read

@RafaelGSS
Copy link
Member

RafaelGSS commented Sep 4, 2025

Benchmark result on my tests:

So, tuns out my computer was too fast and it was delivering the same amount of req/sec regardless of binary. In other words, I was being limited by wrk2 itself. Now I have configured proper values and the latency (which is the most important metric in terms of wrk2) has shown the following distribution:

 50.000%  731.00us
 75.000%    1.02ms
 90.000%    1.22ms
 99.000%    1.85ms
 99.900%    2.05ms
 99.990%    2.15ms
 99.999%    2.26ms
100.000%    2.49ms

node v24.5.0

 50.000%  693.00us
 75.000%    0.98ms
 90.000%    1.16ms
 99.000%    1.51ms
 99.900%    1.99ms
 99.990%    2.18ms
 99.999%    2.60ms
100.000%    2.94ms

And autocannon reported:

node v24.5.0

3164k requests in 30.04s, 576 MB read

versus

4007k requests in 30.04s, 729 MB read

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run. performance Issues and PRs related to the performance of Node.js. request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants