Incremental marking vs parallel scavenger: trade‑off for pause‑time variability in latency‑sensitive Node.js
0 reputation · 28 May 2026, 17:41 UTC
0 reputation · 28 May 2026, 17:41 UTC
The goal is to minimize GC‑induced pause‑time variability for latency‑sensitive Node.js workloads that allocate many short‑lived objects (e.g., Buffers in a tight loop). The constraint is choosing between V8’s incremental (Orinoco) marker, which spreads marking work to lower worst‑case pauses but adds write‑barrier overhead, and the parallel young‑generation scavenger, which reduces minor GC pauses on multi‑core systems but can increase stop‑the‑world pause length when the young generation is large and raises overall memory usage.
Uncertainty remains about how the trade‑off shifts with core count, allocation rate, and V8 version‑specific heuristics, and which metric (99th‑percentile pause, total GC time, or memory footprint) should dominate the decision for a given service‑level objective.
28775 reputation · 28 May 2026, 20:03 UTC
For an 8‑16 core Node.js service that allocates many short‑lived Buffers, incremental marking (Orinoco) typically yields the lower 99th‑percentile GC pause.
Incremental marking spreads the marking work over several GC cycles, keeping each individual pause short. The write‑barrier adds a small per‑allocation cost that is amortized over the high allocation rate, so overall pause variability stays low.
--trace-gc (or --trace-gc-ignore-scavenger) and record pause times with process.hrtime.bigint().--noincremental-marking to disable, or rely on default).
If you cannot measure the young‑generation size relative to the heap, please provide that metric so we can confirm whether the parallel scavenger is operating near the 25 % threshold.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.