Skip to content

Commit 7eafb5b

Browse files
cursoragentanonrig
andcommitted
src: default --v8-pool-size to 1
The default V8 platform pool of 4 worker threads is created during bootstrap. Most processes are I/O bound and never need that parallelism, but still pay for the extra threads and address space. Default the pool to 1. --v8-pool-size=0 still sizes the pool from available parallelism. Assisted-by: Cursor Grok 4.6 Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
1 parent dd5dfb5 commit 7eafb5b

6 files changed

Lines changed: 53 additions & 3 deletions

File tree

doc/api/cli.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3769,6 +3769,7 @@ added: v5.10.0
37693769
-->
37703770

37713771
Set V8's thread pool size which will be used to allocate background jobs.
3772+
The default is `1`.
37723773

37733774
If set to `0` then Node.js will choose an appropriate size of the thread pool
37743775
based on an estimate of the amount of parallelism.

doc/node-config-schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,7 @@
873873
},
874874
"v8-pool-size": {
875875
"type": "number",
876-
"description": "set V8's thread pool size"
876+
"description": "set V8's thread pool size (default: 1; 0 = available parallelism - 1)"
877877
},
878878
"verify-base-objects": {
879879
"type": "boolean",

doc/node.1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,7 @@ Print V8 command-line options.
18731873
.
18741874
.It Fl -v8-pool-size Ns = Ns Ar num
18751875
Set V8's thread pool size which will be used to allocate background jobs.
1876+
The default is 1. 0 sizes the pool from available parallelism.
18761877
If set to \fB0\fR then Node.js will choose an appropriate size of the thread pool
18771878
based on an estimate of the amount of parallelism.
18781879
The amount of parallelism refers to the number of computations that can be

src/node_options.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1523,7 +1523,8 @@ PerProcessOptionsParser::PerProcessOptionsParser(
15231523
AddAlias("--trace-events-enabled", {
15241524
"--trace-event-categories", "v8,node,node.async_hooks" });
15251525
AddOption("--v8-pool-size",
1526-
"set V8's thread pool size",
1526+
"set V8's thread pool size (default: 1; 0 = available "
1527+
"parallelism - 1)",
15271528
&PerProcessOptions::v8_thread_pool_size,
15281529
kAllowedInEnvvar);
15291530
AddOption("--zero-fill-buffers",

src/node_options.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,9 @@ class PerProcessOptions : public Options {
405405
std::vector<std::string> security_reverts;
406406
std::vector<std::string> cmdline;
407407

408-
int64_t v8_thread_pool_size = 4;
408+
// One worker is enough for isolate bootstrap (concurrent compile, GC jobs).
409+
// Use --v8-pool-size=0 to size the pool from available parallelism.
410+
int64_t v8_thread_pool_size = 1;
409411
#if HAVE_OPENSSL
410412
int64_t secure_heap = 0;
411413
int64_t secure_heap_min = 2;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
if (!common.isLinux) {
5+
common.skip('thread names are read from /proc/self/task');
6+
}
7+
8+
const assert = require('assert');
9+
const fs = require('fs');
10+
const { spawnSync } = require('child_process');
11+
12+
function v8WorkerCount() {
13+
return fs.readdirSync('/proc/self/task').reduce((count, tid) => {
14+
try {
15+
const name = fs.readFileSync(`/proc/self/task/${tid}/comm`, 'utf8').trim();
16+
return count + (name === 'node-V8Worker' ? 1 : 0);
17+
} catch {
18+
return count;
19+
}
20+
}, 0);
21+
}
22+
23+
// The default --v8-pool-size is 1, and workers are created at platform init.
24+
assert.strictEqual(v8WorkerCount(), 1);
25+
26+
const script = `
27+
const fs = require('fs');
28+
const n = fs.readdirSync('/proc/self/task').reduce((count, tid) => {
29+
try {
30+
const comm = '/proc/self/task/' + tid + '/comm';
31+
const name = fs.readFileSync(comm, 'utf8').trim();
32+
return count + (name === 'node-V8Worker' ? 1 : 0);
33+
} catch {
34+
return count;
35+
}
36+
}, 0);
37+
process.stdout.write(String(n));
38+
`;
39+
40+
const child = spawnSync(process.execPath, ['--v8-pool-size=4', '-e', script], {
41+
encoding: 'utf8',
42+
});
43+
assert.ifError(child.error);
44+
assert.strictEqual(child.status, 0, child.stderr);
45+
assert.strictEqual(child.stdout, '4');

0 commit comments

Comments
 (0)