Cluster Module

Node.js runs on a single thread. This means only one request is processed at a time inside the event loop.

For normal applications this is fine, but when your app gets high traffic or needs to use all CPU cores, a single Node process becomes a bottleneck.

To solve this, Node.js provides the cluster module, which allows you to create multiple Node processes and use all CPU cores.

Why Use Cluster Module?

The cluster module allows you to create child processes (workers) that share the same server port. This way, you can take advantage of multi-core systems and distribute the load across multiple processes.

  1. 2 cores -> 2 worker processes
  2. 4 cores -> 4 worker processes
  3. 8 cores -> 8 worker processes

Cluster helps:

  1. Use all CPU cores
  2. Handle more requests
  3. Improve app performance
  4. Keep app alive if one process crashes

How cluster works?

To use the cluster module, you need to require or import it in your Node.js application. The cluster module provides methods to create worker processes and manage them.

  1. Node starts a master process
  2. The master creates worker processes (child processes)
  3. Each worker runs your app independently
  4. The master distributes incoming requests among all workers

The master process is responsible for managing worker processes. It listens for events from workers and can restart them if they crash, ensuring the application remains available.


Cluster Example

Here is a simple example of how to use the cluster module in a Node.js application:


const cluster = require("cluster");
const http = require("http");
const os = require("os");

if (cluster.isMaster) {
  const totalCPUs = os.cpus().length;
  console.log(`Master running... CPU Cores: ${totalCPUs}`);

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

  // Restart worker if it crashes
  cluster.on("exit", (worker) => {
    console.log(`Worker ${worker.process.pid} died. Restarting...`);
    cluster.fork();
  });
} else {
  // Workers share same server port
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end(`Handled by worker ${process.pid}`);
  }).listen(3000);

  console.log(`Worker ${process.pid} started`);
}

Explanation

  1. Master creates workers equal to the number of CPU cores
  2. All workers listen on same port (3000)
  3. Requests are shared among them
  4. If a worker crashes, master creates a new one

This gives our app multi-core support.


Cluster in Express

You can also use the cluster module with Express.js to improve the performance of your web applications. Here is an example:


const cluster = require("cluster");
const os = require("os");
const express = require("express");

if (cluster.isPrimary) {
  const cpuCount = os.cpus().length;

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

  cluster.on("exit", (worker) => {
    console.log(`Worker ${worker.process.pid} crashed. Restarting...`);
    cluster.fork();
  });

} else {
  const app = express();

  app.get("/", (req, res) => {
    res.send(`Response from Worker ${process.pid}`);
  });

  app.listen(3000, () => {
    console.log(`Worker ${process.pid} is running`);
  });
}

Explanation

  1. Master creates workers for each CPU core
  2. Each worker runs an Express app
  3. All workers listen on port 3000
  4. Requests are load balanced among workers
  5. If a worker crashes, master restarts it

This setup allows your Express app to handle more traffic efficiently by utilizing all CPU cores.


PM2 for Process Management in production

PM2 is a popular process manager for Node.js applications that makes it easy to manage and keep your app running in production. It provides features like automatic restarts, load balancing, and monitoring.

To use PM2, you first need to install it globally using npm:


npm install -g pm2

Once installed, you can start your Node.js application with PM2 using the following command:


pm2 start app.js -i max

The -i max option tells PM2 to create as many instances of your app as there are CPU cores available, effectively utilizing the cluster module under the hood.

PM2 also provides commands to manage your application, such as:


pm2 list          # List all running processes
pm2 stop      # Stop a specific process
pm2 restart   # Restart a specific process
pm2 monit         # Monitor resource usage