typescriptadvanced

Node.js Cluster Mode for Scaling

Scale Node.js across CPU cores using the cluster module with automatic worker respawning.

typescript
import cluster from 'node:cluster';
import { cpus } from 'node:os';
import { createServer } from 'node:http';

const numCPUs = cpus().length;

if (cluster.isPrimary) {
  console.log(`Primary ${process.pid} starting ${numCPUs} workers`);

  // Fork workers
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  // Respawn crashed workers
  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died (${signal || code})`);
    if (code !== 0) {
      console.log('Starting a new worker...');
      cluster.fork();
    }
  });

  // Graceful restart all workers
  process.on('SIGUSR2', () => {
    const workers = Object.values(cluster.workers || {});
    let i = 0;

    function restartNext() {
      const worker = workers[i];
      if (!worker) return;
      console.log(`Restarting worker ${worker.process.pid}`);

      worker.disconnect();
      worker.on('exit', () => {
        if (!worker.exitedAfterDisconnect) return;
        const newWorker = cluster.fork();
        newWorker.on('listening', () => {
          i++;
          restartNext();
        });
      });
    }

    restartNext();
  });
} else {
  // Worker process
  const server = createServer((req, res) => {
    res.writeHead(200);
    res.end(`Worker ${process.pid} handled request\n`);
  });

  server.listen(3000, () => {
    console.log(`Worker ${process.pid} listening on :3000`);
  });
}

Use Cases

  • Utilizing all CPU cores for HTTP servers
  • Zero-downtime rolling restarts
  • Building resilient production Node.js apps

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.