NodeJS Cluster Module
Written By: Avinash Malhotra
Updated on
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.
- 2 cores -> 2 worker processes
- 4 cores -> 4 worker processes
- 8 cores -> 8 worker processes
Cluster helps:
- Use all CPU cores
- Handle more requests
- Improve app performance
- 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.
- Node starts a master process
- The master creates worker processes (child processes)
- Each worker runs your app independently
- 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
- Master creates workers equal to the number of CPU cores
- All workers listen on same port (3000)
- Requests are shared among them
- 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
- Master creates workers for each CPU core
- Each worker runs an Express app
- All workers listen on port 3000
- Requests are load balanced among workers
- 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