How do you scale a Node.js app? Compare cluster mode and worker_threads.
Take a moment.
Say your answer out loud or write it down first — retrieval is what makes it stick. Reveal when you're ready.
Short answer
cluster forks multiple processes sharing a port — scales throughput across cores, isolates crashes, but no shared memory. worker_threads spawn threads within one process sharing memory via SharedArrayBuffer — right for CPU-bound computation. Use both: cluster × workers.
Detailed explanation
Node's single-threaded main loop uses one core by default; scaling strategies differ by bottleneck. cluster module forks N worker processes, each a full Node instance; the master distributes connections across them (round-robin typically). Benefits: uses all cores, a crashed worker restarts independently (resilience), zero shared-state complexity — communicate via IPC. Cost: duplicated memory, no direct state sharing (sessions need Redis etc.). worker_threads creates true threads inside one process sharing heap optionally (SharedArrayBuffer, transferable ArrayBuffers) — designed for parallelizing computation: image resizing, hashing, parsing, not for adding request capacity. Rule of thumb: more requests → cluster; faster single requests → workers. In containers/Kubernetes, orchestrators often replace cluster (one process per container, scale pods horizontally), making worker_threads the in-process tool. PM2 wraps clustering with zero-downtime reloads for VM deployments.
Example
// cluster.js — use all cores
import cluster from 'node:cluster';
import os from 'node:os';
if (cluster.isPrimary) {
for (let i = 0; i < os.availableParallelism(); i++) cluster.fork();
cluster.on('exit', (worker) => {
console.log(`worker ${worker.process.pid} died — restarting`);
cluster.fork();
});
} else {
await import('./server.js'); // each worker listens on same port
}
// CPU-bound task → worker_threads instead:
// new Worker('./heavy-hash.js', { workerData: payload })Interview tip
Draw the decision line clearly — horizontal request capacity = cluster/pods; parallel computation = worker_threads. Mentioning container orchestration replacing cluster shows production maturity.
Common mistakes
- Using worker_threads expecting higher request throughput.
- Not knowing cluster workers share nothing in memory.