Skip to content

Commit dc5a20c

Browse files
committed
src: set UV_THREADPOOL_SIZE based on available parallelism
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.
1 parent 38647b3 commit dc5a20c

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

src/node.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,24 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
12201220
#endif // HAVE_OPENSSL
12211221
}
12221222

1223+
// Set UV_THREADPOOL_SIZE based on available parallelism if not already set
1224+
// by the user. The libuv threadpool defaults to 4 threads, which can be
1225+
// suboptimal on machines with many CPU cores. Use uv_available_parallelism()
1226+
// as a heuristic, with a minimum of 4 (the previous default) and a maximum
1227+
// of 1024 (libuv's upper bound).
1228+
{
1229+
char buf[64];
1230+
size_t buf_size = sizeof(buf);
1231+
int rc = uv_os_getenv("UV_THREADPOOL_SIZE", buf, &buf_size);
1232+
if (rc == UV_ENOENT) {
1233+
unsigned int parallelism = uv_available_parallelism();
1234+
unsigned int threadpool_size = std::min(std::max(4u, parallelism), 1024u);
1235+
char size_str[16];
1236+
snprintf(size_str, sizeof(size_str), "%u", threadpool_size);
1237+
uv_os_setenv("UV_THREADPOOL_SIZE", size_str);
1238+
}
1239+
}
1240+
12231241
if (!(flags & ProcessInitializationFlags::kNoInitializeNodeV8Platform)) {
12241242
uv_thread_setname("node-MainThread");
12251243
per_process::v8_platform.Initialize(
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
const { spawnSyncAndAssert } = require('../common/child_process');
3+
const assert = require('assert');
4+
const os = require('os');
5+
6+
const expectedSize = Math.min(Math.max(4, os.availableParallelism()), 1024);
7+
8+
// When UV_THREADPOOL_SIZE is not set, Node.js should auto-size it based on
9+
// uv_available_parallelism(), with a minimum of 4 and a maximum of 1024.
10+
{
11+
const env = { ...process.env };
12+
delete env.UV_THREADPOOL_SIZE;
13+
14+
spawnSyncAndAssert(
15+
process.execPath,
16+
['-e', 'console.log(process.env.UV_THREADPOOL_SIZE)'],
17+
{ env },
18+
{
19+
stdout(output) {
20+
assert.strictEqual(output.trim(), String(expectedSize));
21+
},
22+
},
23+
);
24+
}
25+
26+
// When UV_THREADPOOL_SIZE is explicitly set, Node.js should not override it.
27+
{
28+
const env = { ...process.env, UV_THREADPOOL_SIZE: '8' };
29+
30+
spawnSyncAndAssert(
31+
process.execPath,
32+
['-e', 'console.log(process.env.UV_THREADPOOL_SIZE)'],
33+
{ env },
34+
{
35+
stdout(output) {
36+
assert.strictEqual(output.trim(), '8');
37+
},
38+
},
39+
);
40+
}

0 commit comments

Comments
 (0)