0
0
NodejsHow-ToBeginner · 4 min read

How to Scale Node.js Using Cluster for Better Performance

Use the cluster module in Node.js to create multiple worker processes that share the same server port, allowing your app to use all CPU cores. The master process manages workers, improving performance and reliability by balancing load and restarting workers if they crash.
📐

Syntax

The cluster module lets you create a master process and multiple worker processes. The master controls workers, and each worker runs your server code.

  • cluster.isMaster: Checks if the current process is the master.
  • cluster.fork(): Creates a new worker process.
  • cluster.on('exit'): Listens for worker exit events to restart them.
javascript
import cluster from 'cluster';
import os from 'os';

if (cluster.isMaster) {
  const cpuCount = os.cpus().length;
  for (let i = 0; i < cpuCount; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died, restarting...`);
    cluster.fork();
  });
} else {
  // Worker process code here
  // e.g., start HTTP server
}
💻

Example

This example shows a simple HTTP server scaled across all CPU cores using cluster. The master forks workers equal to CPU count. Each worker runs the server on the same port, sharing the load.

javascript
import cluster from 'cluster';
import http from 'http';
import os from 'os';

const PORT = 3000;

if (cluster.isMaster) {
  const cpuCount = os.cpus().length;
  console.log(`Master ${process.pid} is running`);

  for (let i = 0; i < cpuCount; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died, restarting...`);
    cluster.fork();
  });
} else {
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end(`Hello from worker ${process.pid}\n`);
  }).listen(PORT);

  console.log(`Worker ${process.pid} started`);
}
Output
Master 12345 is running Worker 12346 started Worker 12347 started Worker 12348 started Worker 12349 started
⚠️

Common Pitfalls

Common mistakes when using cluster include:

  • Not handling worker crashes, which can cause downtime.
  • Trying to share state directly between workers (each worker has its own memory).
  • Binding server to different ports in each worker instead of the same port.
  • Not restarting workers on exit, losing capacity.

Always use cluster.on('exit') to restart workers and use external storage or messaging for shared state.

javascript
import cluster from 'cluster';
import http from 'http';
import os from 'os';

const PORT = 3000;

if (cluster.isMaster) {
  const cpuCount = os.cpus().length;
  for (let i = 0; i < cpuCount; i++) {
    cluster.fork();
  }

  // Missing restart on exit (wrong way)
  // cluster.on('exit', (worker) => {
  //   console.log(`Worker ${worker.process.pid} died`);
  // });

  // Correct way:
  cluster.on('exit', (worker) => {
    console.log(`Worker ${worker.process.pid} died, restarting...`);
    cluster.fork();
  });
} else {
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end(`Hello from worker ${process.pid}\n`);
  }).listen(PORT);
}
📊

Quick Reference

Tips for scaling Node.js with cluster:

  • Use os.cpus().length to fork one worker per CPU core.
  • Always restart workers on exit to keep your app running smoothly.
  • Do not share memory between workers; use external stores like Redis if needed.
  • Bind all workers to the same port to share incoming connections.
  • Use cluster.isMaster to separate master and worker logic.

Key Takeaways

Use the Node.js cluster module to fork worker processes equal to CPU cores for better performance.
The master process manages workers and restarts them if they crash to ensure reliability.
Workers share the same server port to balance incoming requests across CPUs.
Avoid sharing memory between workers; use external storage for shared state.
Always handle worker exit events to restart workers automatically.