advanced

Worker threads

Move CPU-heavy work to worker threads with message passing, transfer lists, shared memory, and lifecycle control.

Worker threads run JavaScript in separate V8 isolates with message-passing communication — the right tool for CPU-bound JS, not a replacement for cluster scaling.

					import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';

if (isMainThread) {
  const worker = new Worker(new URL(import.meta.url), {
    workerData: { primesUpTo: 500_000 },
  });
  worker.on('message', (result) => console.log(result));
} else {
  const count = countPrimes(workerData.primesUpTo);
  parentPort.postMessage({ count });
}
				

Transfer lists move ArrayBuffer ownership without copying. `SharedArrayBuffer` enables low-level shared memory but requires careful synchronization.

Workers have startup cost and separate memory — batch work per message instead of chatty fine-grained RPC.

On interviews: contrast workers (threads + shared process) with cluster (processes) and child processes; explain when workers beat async I/O.

Common pitfalls: passing large objects without transfer lists; sharing mutable state without Atomics; spawning workers per request under load.

Checklist:

  • Use workers for CPU-heavy pure JS.
  • Transfer ArrayBuffers when possible.
  • Pool workers and reuse lifecycle.
  • Keep messages coarse-grained.