Skip to content

Conversation

@RafaelGSS
Copy link
Member

@RafaelGSS RafaelGSS commented Jan 26, 2026

When UV_THREADPOOL_SIZE is not set, Node.js will auto-size it based on uv_available_parallelism(), with a minimum of 4 and a maximum of 1024.

Refs: nodejs/performance#193

image

I will still run some benchmarks to see its real impact. Adding blocked label for now.

cc: @ronag

When UV_THREADPOOL_SIZE is not set, Node.js will auto-size it based on
uv_available_parallelism(), with a minimum of 4 and a maximum of 1024.
@RafaelGSS RafaelGSS added semver-major PRs that contain breaking changes and should be released in the next major version. blocked PRs that are blocked by other issues or PRs. notable-change PRs with changes that should be highlighted in changelogs. labels Jan 26, 2026
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/startup

@github-actions
Copy link
Contributor

The notable-change PRs with changes that should be highlighted in changelogs. label has been added by @RafaelGSS.

Please suggest a text for the release notes if you'd like to include a more detailed summary, then proceed to update the PR description with the text or a link to the notable change suggested text comment. Otherwise, the commit will be placed in the Other Notable Changes section.

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Jan 26, 2026
@codecov
Copy link

codecov bot commented Jan 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.75%. Comparing base (644ba1f) to head (56c47e8).
⚠️ Report is 135 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #61533      +/-   ##
==========================================
- Coverage   89.76%   89.75%   -0.01%     
==========================================
  Files         672      675       +3     
  Lines      203809   204650     +841     
  Branches    39189    39324     +135     
==========================================
+ Hits       182949   183693     +744     
- Misses      13179    13243      +64     
- Partials     7681     7714      +33     
Files with missing lines Coverage Δ
src/node.cc 76.53% <100.00%> (+0.44%) ⬆️

... and 92 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@juanarbol juanarbol left a comment

Choose a reason for hiding this comment

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

lgtm

Copy link
Member

@ronag ronag left a comment

Choose a reason for hiding this comment

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

LGTM.

Though I think there is some confusion here regarding parallelism vs concurrency. It can be meaningful to have more io dispatch threads than logical cpus. The task of the uv thread pool (in the case of fs) is to dispatch io and wait for results. So if your hardware can do 128 io requests in parallel you only need to dispatch 128 io requests concurrently which you can do on e.g. 16 logical cpus / available parallelism as well. In the opposite end, if your io hardware only has 128 parallel requests, than having more than 128 worker threads is not meaningful.

The whole thing with the "right" number of threads is super complicated with the current architecture. If we used ioring instead for fs then available parallelism would be the perfect amount.

That being said, I think available parallelism is a good guess but far from being a guaranteed optimal.

Copy link
Contributor

@Ethan-Arrowood Ethan-Arrowood left a comment

Choose a reason for hiding this comment

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

I'm generally in favor of this change. Though I appreciate more research on if this is better for overall performance. I did something similar for picking a more sensible Node.js test_runner parallelization number for resource intensive tests. You're welcome to evaluate/use/reference my process and code here: https://github.com/Ethan-Arrowood/node-test-runner-parallelization-analysis

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

@RafaelGSS RafaelGSS added the performance Issues and PRs related to the performance of Node.js. label Jan 28, 2026
Copy link
Member

@gurgunday gurgunday left a comment

Choose a reason for hiding this comment

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

lgtm

@Flarna
Copy link
Member

Flarna commented Feb 1, 2026

Which overhead (e.g. memory) is expected per uv thread?
I could imagine it's not negligible if number goes from 4 to 1024.

@bricss
Copy link
Contributor

bricss commented Feb 2, 2026

Note: Under most optimal conditions, the value 🔢 shall never exceed the following formula:
export UV_THREADPOOL_SIZE=$(($(nproc) * 2))

@RafaelGSS
Copy link
Member Author

RafaelGSS commented Feb 6, 2026

I took some time today, and I did the following measurement:

Benchmark Results: PR vs Node.js v24.13.0

This report compares the performance of the PR Build against the Baseline (v24.13.0) across three machine configurations: 2GB, 8GB, and 32GB.

Machine Configurations (lscpu)

Machine CPUs Model RAM Notes
2GB 2 AMD EPYC-Rome @ 2.0GHz 2GB Small instance
8GB 4 AMD EPYC-Rome @ 2.0GHz 8GB Medium instance
32GB 16 AMD EPYC-Rome @ 2.0GHz 32GB Large instance

1. 32GB Machine (16 vCPUs)

PR Threadpool: 16 | Baseline Threadpool: 4

Endpoint Metric PR Baseline Difference
/crypto Req/Sec 466,679 122,350 +281.42%
Avg Latency 35.71 ms 137.34 ms -73.99%
/fs Req/Sec 1,548,970 1,830,365 -15.37%
Avg Latency 10.41 ms 8.74 ms +19.10%
/mixed Req/Sec 1,230,062 651,400 +88.83%
Avg Latency 13.25 ms 25.45 ms -47.93%

2. 8GB Machine (4 vCPUs)

PR Threadpool: 4 | Baseline Threadpool: 4

Endpoint Metric PR Baseline Difference
/crypto Req/Sec 100,970 100,859 +0.11%
/fs Req/Sec 1,439,445 1,480,260 -2.76%
/mixed Req/Sec 495,552 511,667 -3.15%

3. 2GB Machine (2 vCPUs)

PR Threadpool: 4 | Baseline Threadpool: 4*

Endpoint Metric PR Baseline Difference
/crypto Req/Sec 59,074 59,651 -0.97%
/fs Req/Sec 1,836,680 1,892,625 -2.96%
/mixed Req/Sec 337,245 349,286 -3.45%

If you have dedicated machines, feel free to run: curl -sL https://raw.githubusercontent.com/RafaelGSS/uv-threadpool-benchmark/main/benchmark.sh | bash

@ronag
Copy link
Member

ronag commented Feb 8, 2026

Didn't go so swell:


============================================================
SUMMARY
============================================================

Route: /crypto
  Requests:       0
  Throughput:     0.00 req/sec
  Latency (avg):  0.00 ms
  Latency (p99):  0.00 ms
  Errors:         1380543
  Timeouts:       0

Route: /fs
  Requests:       0
  Throughput:     0.00 req/sec
  Latency (avg):  0.00 ms
  Latency (p99):  0.00 ms
  Errors:         1369912
  Timeouts:       0

Route: /mixed
  Requests:       0
  Throughput:     0.00 req/sec
  Latency (avg):  0.00 ms
  Latency (p99):  0.00 ms
  Errors:         1366417
  Timeouts:       0
Failed to fetch metrics: fetch failed


Stopping server...
bash: line 81: kill: (1658) - No such process

@RafaelGSS
Copy link
Member Author

Which OS? @ronag

@ronag
Copy link
Member

ronag commented Feb 9, 2026

Which OS? @ronag

Official mode docker image

@RafaelGSS
Copy link
Member Author

@ronag do you have the commands you run? It seems your server didn't have permissions to get up, so the benchmark tool couldn't measure that.

@ronag
Copy link
Member

ronag commented Feb 10, 2026

hq-test-srv1.local:~# docker run -it node:latest bash
Unable to find image 'node:latest' locally
latest: Pulling from library/node
6bc9f599b3ef: Pull complete 
89edcaae7ec4: Pull complete 
bbceb0035429: Pull complete 
6dc8224e38b6: Pull complete 
514a5393d1c3: Pull complete 
c4773027f0a7: Pull complete 
86c20919419f: Pull complete 
073cbdc3d24d: Pull complete 
Digest: sha256:3523df9d45c0280f49f4b503c7e2d354eeab5d676017488dd082188a0f09f99a
Status: Downloaded newer image for node:latest
root@cc0bc5856faf:/#  curl -sL https://raw.githubusercontent.com/RafaelGSS/uv-threadpool-benchmark/main/benchmark.sh | bash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked PRs that are blocked by other issues or PRs. c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. notable-change PRs with changes that should be highlighted in changelogs. performance Issues and PRs related to the performance of Node.js. 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.

10 participants