Skip to content

Commit 257e25b

Browse files
committed
perf(core): limit each worker's heap to 512MB
V8 lets a heap grow to several times its live data before collecting it, the more the higher its limit: four times from 2GB up, and on a machine with plenty of memory every worker's limit is 4GB, so each held several times what it was using. Each worker's old space is now limited to `WORKER_HEAP_SIZE` (512MB). The biggest page of the Node.js docs, `all.html`, takes ~300MB. Node's `--max-old-space-size` replaces the limit, to raise it, and it's what limits the main thread, which runs the generators with one thread. On Node core's build with 4 threads, the peak goes from 2.02GB to 1.67GB on Node 26, and from 2.44GB to 2.19GB on Node 24, for 3-5% more time spent collecting garbage. The build passes with workers limited to as little as ~350MB. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent f42695e commit 257e25b

3 files changed

Lines changed: 15 additions & 1 deletion

File tree

‎docs/configuration.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ these for that generator alone, except `markdown`, which it adds to.
134134
Top-level, alongside `target` and `global`:
135135

136136
- `threads` {number} Worker threads used for generation. Defaults to your
137-
CPU count.
137+
CPU count. Each worker's heap is limited to 512MB; raise it with Node.js's
138+
`--max-old-space-size` (`NODE_OPTIONS` takes it too).
138139
- `chunkSize` {number} Items processed per worker thread. **Default:** `10`.
139140

140141
## Generator options
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
3+
/**
4+
* The heap size limit of each worker thread (V8's old space), in MB. V8 lets a
5+
* heap grow to several times its live data before collecting it, the more the
6+
* higher its limit, so every worker held several times what it was using. The
7+
* biggest page of the Node.js docs, `all.html`, takes ~300MB. Node.js's
8+
* `--max-old-space-size` replaces it.
9+
*/
10+
export const WORKER_HEAP_SIZE = 512;

‎packages/core/src/threading/index.mjs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import Piscina from 'piscina';
22

33
import logger from '#logger/index.mjs';
44

5+
import { WORKER_HEAP_SIZE } from './constants.mjs';
6+
57
const poolLogger = logger.child('WorkerPool');
68

79
const workerScript = import.meta.resolve('./chunk-worker.mjs');
@@ -23,6 +25,7 @@ export default function createWorkerPool(threads) {
2325
minThreads: 0,
2426
maxThreads: threads,
2527
idleTimeout: 1_000,
28+
resourceLimits: { maxOldGenerationSizeMb: WORKER_HEAP_SIZE },
2629
workerData: { logLevel: logger.getLogLevel() },
2730
});
2831
}

0 commit comments

Comments
 (0)