X Tutup
The Wayback Machine - https://web.archive.org/web/20230215125632/https://github.com/nodejs/node/pull/46608
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stream: bump default highWaterMark #46608

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

ronag
Copy link
Member

@ronag ronag commented Feb 10, 2023

This should give a performance boost accross the board at the cost of slightly higher memory usage.

Given that the old limit is a decode old and memory capacity has doubled many times since I think it is appropriate to slightly bump the default limit.

This should give a performance boost accross the board at the
cost of slightly higher memory usage.

Given that the old limit is a decode old and memory capacity has
doubled many times since I think it is appropriate to slightly bump
the default limit.
@ronag ronag added the stream Issues and PRs related to the stream subsystem. label Feb 10, 2023
@ronag ronag requested a review from mcollina February 10, 2023 15:12
@nodejs-github-bot
Copy link
Contributor

Review requested:

  • @nodejs/streams

@nodejs-github-bot nodejs-github-bot added the needs-ci PRs that need a full CI run. label Feb 10, 2023
@ronag
Copy link
Member Author

ronag commented Feb 10, 2023

TBH I would like to bump it even further to 128k but I don't think I will get consensus on that one.

@mcollina mcollina added semver-minor PRs that contain new features and should be released in the next minor version. dont-land-on-v14.x PRs that should not land on the v14.x-staging branch and should not be released in v14.x. dont-land-on-v16.x PRs that should not land on the v16.x-staging branch and should not be released in v16.x. dont-land-on-v18.x PRs that should not land on the v18.x-staging branch and should not be released in v18.x. baking-for-lts PRs that need to wait before landing in a LTS release. and removed dont-land-on-v14.x PRs that should not land on the v14.x-staging branch and should not be released in v14.x. dont-land-on-v16.x PRs that should not land on the v16.x-staging branch and should not be released in v16.x. dont-land-on-v18.x PRs that should not land on the v18.x-staging branch and should not be released in v18.x. labels Feb 10, 2023
@mcollina
Copy link
Member

I've put in the "baking for lts" label to wait a bit to backport in case of issues.

FWIW I think bumping this to 128KB is acceptable. It would help reduce overhead.

cc @mscdex @cjihrig

@ronag ronag added request-ci Add this label to start a Jenkins CI on a PR. and removed needs-ci PRs that need a full CI run. labels Feb 10, 2023
@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 Feb 10, 2023
@github-actions
Copy link
Contributor

Failed to start CI
- Validating Jenkins credentials
✖  Jenkins credentials invalid
https://github.com/nodejs/node/actions/runs/4145265543

Copy link
Contributor

@mscdex mscdex left a comment

Choose a reason for hiding this comment

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

-1 I don't think we should do this. Node runs on all kinds of setups, including more resource-constrained hardware. The current defaults work well memory usage-wise in either kind of setup.

I think a better solution would be to allow end users to set something like Stream.defaultObjectWaterMark/Stream.defaultWaterMark which would default to the current 16/16KB respectively.

This way users could just set this at the top of their main script and get the same effect if they want to take on that kind of potential extra memory consumption.

@lpinca
Copy link
Member

lpinca commented Feb 10, 2023

My memory tells me that this was already proposed in the past but I can't find the PRs/issues. I kind of agree with @mscdex. Instead of changing the default for everyone, make it customizable.

@ronag
Copy link
Member Author

ronag commented Feb 10, 2023

The problem with that is that most users will not bother/dare/known how to set it. So we are slowing it down for everyone to be compatible with a few... not saying that's wrong, but is there any middle ground? Can we e.g. check the total available system memory and base it on that?

Messing around with hwm and Buffer.poolSize is kind of advanced user usage.

@mscdex
Copy link
Contributor

mscdex commented Feb 10, 2023

The problem with that is that most users will not bother/dare/known how to set it.

The properties I proposed would be in the documentation, which I think developers would already be looking at (especially if they are at the point where the stream high water mark is actually becoming a bottleneck), so I don't see this as an issue.

So we are slowing it down for everyone to be compatible with a few... not saying that's wrong

It could be argued both ways. I don't think it's fair to say that everyone is running node in environments where memory usage is not a concern.

but is there any middle ground?

I believe what I proposed is a middle ground. Besides, we already employ similar user-tweakable limits throughout node core, so this would just be making things more consistent in that regard.

Can we e.g. check the total available system memory and base it on that?

I don't think there is any realistic way of doing something like this as that'd be making the assumption that the node process is the only thing running on the OS that is using any considerable amount of resources.

Copy link
Member

@benjamingr benjamingr left a comment

Choose a reason for hiding this comment

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

I agree there is a tradeoff here and nuance but I think we're currently too conservative and so agree with this change. Constrained systems can usually override this.

@LiviaMedeiros
Copy link
Contributor

@ronag unrelated to contents of this PR but why the removal of needs-ci PRs that need a full CI run. label?
Correct me if I'm wrong but AFAIR it's a safety measure to prevent accidental merging of PRs with failing CI: https://github.com/nodejs/node-core-utils/blob/267dde0692d42e2482d133d4cccfcae13586ad89/lib/pr_checker.js#L429-L440
So this should be always kept (arguably with exception of doc-only PRs, trivial linting, etc.)

@BridgeAR
Copy link
Member

Can we e.g. check the total available system memory and base it on that?

I don't think there is any realistic way of doing something like this as that'd be making the assumption that the node process is the only thing running on the OS that is using any considerable amount of resources.

Increasing the highWaterMark is going to finish the process faster and thus, could actually lead to less memory pressure for high load scenarios.

So we are slowing it down for everyone to be compatible with a few... not saying that's wrong

It could be argued both ways. I don't think it's fair to say that everyone is running node in environments where memory usage is not a concern.

Our defaults are always concern for debate and we will likely never have the correct default for everyone. What we should IMO strive for is a default that is best for most users, so that only a few have to change the them. Many users are not aware of these things and only check for them, in case they know, they have to be cautious (what I would expect for users running in an environment where memory is a concern).

Using a heuristic where we check for the available memory sounds like a good idea to me. That way we will likely have the right setting for more users than we have currently. One difficult part might be to define the thresholds and what memory to look at (overall memory vs. free memory). For now, I would just use process.constrainedMemory() and default to the lower default in case undefined is returned.

@vweevers
Copy link
Contributor

Heuristics can't tell how many parallel streams will be created and what the intended purpose of the available memory is. I like that streams slow down and leave room.

I also prefer baby steps here. The effect of increasing a hardcoded default is relatively easy to measure and doesn't mess with user expectations that much, compared to heuristics. Increasing the hwm every so often (and gradually) can improve performance for a majority of users, while still giving others a chance to test it out (even unknowingly).

@ronag
Copy link
Member Author

ronag commented Feb 11, 2023

@ronag unrelated to contents of this PR but why the removal of needs-ci PRs that need a full CI run. label?

Correct me if I'm wrong but AFAIR it's a safety measure to prevent accidental merging of PRs with failing CI: https://github.com/nodejs/node-core-utils/blob/267dde0692d42e2482d133d4cccfcae13586ad89/lib/pr_checker.js#L429-L440

So this should be always kept (arguably with exception of doc-only PRs, trivial linting, etc.)

We don't land anything without CI. Don't worry. I just missed adding the request-ci label.

@lpinca
Copy link
Member

lpinca commented Feb 11, 2023

This increases the HWM by eight times while leaving the default for object mode unchanged. It will increase memory usage by eight times on a proxy that pipes data to a slower destination. That is almost an order of magnitude.

FWIW we are using 64 KiB for file system streams.

@mcollina
Copy link
Member

mcollina commented Feb 11, 2023

I'd be ok in doing baby steps with this.

How about we increase the highwatermarks to 64KB? I think matching file system streams is a safe choice.

@ronag
Copy link
Member Author

ronag commented Feb 11, 2023

Changed to 64k

@ronag
Copy link
Member Author

ronag commented Feb 11, 2023

@mscdex Are you still objecting?

@ronag ronag added request-ci Add this label to start a Jenkins CI on a PR. review wanted PRs that need reviews. and removed request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. labels Feb 11, 2023
@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 Feb 11, 2023
@github-actions
Copy link
Contributor

Failed to start CI
- Validating Jenkins credentials
✖  Jenkins credentials invalid
https://github.com/nodejs/node/actions/runs/4150907588

@jasnell
Copy link
Member

jasnell commented Feb 11, 2023

Needs a test :-)

@cjihrig
Copy link
Contributor

cjihrig commented Feb 11, 2023

The problem with that is that most users will not bother/dare/known how to set it.

I think a better solution would be to allow end users to set something like Stream.defaultObjectWaterMark/Stream.defaultWaterMark which would default to the current 16/16KB respectively.

I like this idea because it becomes an easy way to change the default, and we could adjust "default default" more easily in semver major changes.

@ronag
Copy link
Member Author

ronag commented Feb 13, 2023

Added test. @jasnell

@ronag ronag requested review from jasnell and lpinca February 13, 2023 07:38
@ronag ronag added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. labels Feb 15, 2023
@ronag
Copy link
Member Author

ronag commented Feb 15, 2023

@mscdex ping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
baking-for-lts PRs that need to wait before landing in a LTS release. request-ci Add this label to start a Jenkins CI on a PR. review wanted PRs that need reviews. semver-minor PRs that contain new features and should be released in the next minor version. stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

X Tutup