diff --git a/doc/api/cli.md b/doc/api/cli.md index 1fd1e9864338..2f649e443478 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -3769,6 +3769,7 @@ added: v5.10.0 --> Set V8's thread pool size which will be used to allocate background jobs. +The default is `1`. If set to `0` then Node.js will choose an appropriate size of the thread pool based on an estimate of the amount of parallelism. diff --git a/doc/node-config-schema.json b/doc/node-config-schema.json index 07d4ac4a64ee..1498c7ba12e1 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -873,7 +873,7 @@ }, "v8-pool-size": { "type": "number", - "description": "set V8's thread pool size" + "description": "set V8's thread pool size (default: 1; 0 = available parallelism - 1)" }, "verify-base-objects": { "type": "boolean", diff --git a/doc/node.1 b/doc/node.1 index 1b873d1eccaa..aadac2646a95 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -1873,6 +1873,7 @@ Print V8 command-line options. . .It Fl -v8-pool-size Ns = Ns Ar num Set V8's thread pool size which will be used to allocate background jobs. +The default is 1. 0 sizes the pool from available parallelism. If set to \fB0\fR then Node.js will choose an appropriate size of the thread pool based on an estimate of the amount of parallelism. The amount of parallelism refers to the number of computations that can be diff --git a/src/node_options.cc b/src/node_options.cc index 89c2d66b3942..03c209984aa2 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -1523,7 +1523,8 @@ PerProcessOptionsParser::PerProcessOptionsParser( AddAlias("--trace-events-enabled", { "--trace-event-categories", "v8,node,node.async_hooks" }); AddOption("--v8-pool-size", - "set V8's thread pool size", + "set V8's thread pool size (default: 1; 0 = available " + "parallelism - 1)", &PerProcessOptions::v8_thread_pool_size, kAllowedInEnvvar); AddOption("--zero-fill-buffers", diff --git a/src/node_options.h b/src/node_options.h index cad2e850e316..2a696a2de3d7 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -405,7 +405,9 @@ class PerProcessOptions : public Options { std::vector security_reverts; std::vector cmdline; - int64_t v8_thread_pool_size = 4; + // One worker is enough for isolate bootstrap (concurrent compile, GC jobs). + // Use --v8-pool-size=0 to size the pool from available parallelism. + int64_t v8_thread_pool_size = 1; #if HAVE_OPENSSL int64_t secure_heap = 0; int64_t secure_heap_min = 2; diff --git a/test/parallel/test-v8-pool-size-default.js b/test/parallel/test-v8-pool-size-default.js new file mode 100644 index 000000000000..920171f47c5f --- /dev/null +++ b/test/parallel/test-v8-pool-size-default.js @@ -0,0 +1,45 @@ +'use strict'; + +const common = require('../common'); +if (!common.isLinux) { + common.skip('thread names are read from /proc/self/task'); +} + +const assert = require('assert'); +const fs = require('fs'); +const { spawnSync } = require('child_process'); + +function v8WorkerCount() { + return fs.readdirSync('/proc/self/task').reduce((count, tid) => { + try { + const name = fs.readFileSync(`/proc/self/task/${tid}/comm`, 'utf8').trim(); + return count + (name === 'node-V8Worker' ? 1 : 0); + } catch { + return count; + } + }, 0); +} + +// The default --v8-pool-size is 1, and workers are created at platform init. +assert.strictEqual(v8WorkerCount(), 1); + +const script = ` + const fs = require('fs'); + const n = fs.readdirSync('/proc/self/task').reduce((count, tid) => { + try { + const comm = '/proc/self/task/' + tid + '/comm'; + const name = fs.readFileSync(comm, 'utf8').trim(); + return count + (name === 'node-V8Worker' ? 1 : 0); + } catch { + return count; + } + }, 0); + process.stdout.write(String(n)); +`; + +const child = spawnSync(process.execPath, ['--v8-pool-size=4', '-e', script], { + encoding: 'utf8', +}); +assert.ifError(child.error); +assert.strictEqual(child.status, 0, child.stderr); +assert.strictEqual(child.stdout, '4');