The Cluster Module allows a Node.js application to use multiple CPU cores by creating multiple Node.js processes (workers).
Why Cluster is Needed?
Node.js runs on a single thread.
Example:
const express = require("express");
const app = express();
app.listen(5000);
Even if your server has:
CPU Core 1
CPU Core 2
CPU Core 3
CPU Core 4
CPU Core 5
CPU Core 6
CPU Core 7
CPU Core 8
Node will use only:
CPU Core 1
The remaining cores stay idle.
Without Cluster
10000 Requests
|
v
Node Process
|
CPU Core 1
Problems:
High CPU Usage
Slow Response
Single Point Failure
With Cluster
Master Process
|
-----------------------------------------
| | | |
Worker 1 Worker 2 Worker 3 Worker 4
Each worker is a separate Node.js process.
Basic Example
const cluster = require("cluster");
const os = require("os");
if (cluster.isPrimary) {
console.log("Master Process");
} else {
console.log("Worker Process");
}
Output:
Master Process
Because only one process exists.
Create Workers
const cluster = require("cluster");
const os = require("os");
const cpuCount = os.cpus().length;
if (cluster.isPrimary) {
console.log(`Master PID: ${process.pid}`);
for (let i = 0; i < cpuCount; i++) {
cluster.fork();
}
}
Suppose machine has 8 cores.
Output:
Master PID: 1000
Worker PID: 1001
Worker PID: 1002
Worker PID: 1003
Worker PID: 1004
Worker PID: 1005
Worker PID: 1006
Worker PID: 1007
Worker PID: 1008
Full Express Example
const cluster = require("cluster");
const os = require("os");
const express = require("express");
const cpuCount = os.cpus().length;
if (cluster.isPrimary) {
console.log(`Master ${process.pid}`);
for (let i = 0; i < cpuCount; i++) {
cluster.fork();
}
} else {
const app = express();
app.get("/", (req, res) => {
res.send(
`Response from Worker ${process.pid}`
);
});
app.listen(5000, () => {
console.log(
`Worker ${process.pid} started`
);
});
}
How Requests are Distributed?
Request 1 → Worker 1
Request 2 → Worker 2
Request 3 → Worker 3
Request 4 → Worker 4
Request 5 → Worker 1
This is Round Robin.
Master
|
--------------------------------
| | | |
W1 W2 W3 W4
Master process distributes requests.
Worker Crash Recovery
Suppose:
Worker 3 Crashes
Without restart:
W1
W2
X
W4
Application capacity reduces.
Auto Restart Workers
const cluster = require("cluster");
const os = require("os");
const cpuCount = os.cpus().length;
if (cluster.isPrimary) {
for (let i = 0; i < cpuCount; i++) {
cluster.fork();
}
cluster.on("exit", (worker) => {
console.log(
`Worker ${worker.process.pid} died`
);
cluster.fork();
});
}
Now:
Worker 1003 Died
↓
New Worker 1010 Started
Self-healing system.
IPC (Inter Process Communication)
Workers can communicate with Master.
Worker:
process.send({
message: "User Created"
});
Master:
cluster.on("message",
(worker, message) => {
console.log(message);
});
Output:
User Created
Shared Memory?
Workers do NOT share memory.
Worker 1:
let counter = 10;
Worker 2:
console.log(counter);
Output:
undefined
Because:
Worker 1 Memory
Worker 2 Memory
Worker 3 Memory
are separate.
Problem Example
let onlineUsers = 0;
Request 1:
Worker 1
onlineUsers = 1
Request 2:
Worker 2
onlineUsers = 1
Actual users:
2
But each worker thinks:
1
Wrong data.
Solution
Store shared data in:
Redis
await redis.incr("onlineUsers");
MongoDB
await User.updateOne(...);
MySQL
UPDATE counter
SET total = total + 1;
Never store shared data in worker memory.
Cluster + MongoDB
Each worker creates its own connection pool.
Worker 1 → Mongo Pool
Worker 2 → Mongo Pool
Worker 3 → Mongo Pool
Worker 4 → Mongo Pool
Example:
mongoose.connect(
process.env.MONGO_URI,
{
maxPoolSize: 10
}
);
If 4 workers:
4 × 10 = 40 Connections
Need to size your database accordingly.
Cluster + Redis
Very common.
Users
|
Cluster Workers
|
Redis Cache
|
MongoDB
Benefits:
Fast
Shared Session
Shared Cache
Shared Counters
Real Example: Job Portal
Internet
|
v
Node Cluster
|
-----------------------------------
| | | |
W1 W2 W3 W4
|
Redis Cache
|
MongoDB
Flow:
User opens jobs page
↓
Worker 2 receives request
↓
Check Redis
↓
Return cache
OR
Fetch MongoDB
↓
Save Redis
↓
Return result
Drawbacks of Cluster
1. Memory Usage
Each worker:
Express
Middleware
Routes
Models
are loaded separately.
Example:
1 Worker = 150 MB
8 Workers
= 1200 MB
2. Shared State Issue
Cannot use:
let counter = 0;
for global application state.
Need Redis/Database.
3. More Database Connections
More workers:
More DB Connections
Need proper pooling.
Cluster vs PM2
Cluster Module
You manage workers manually
You write cluster code
Example:
cluster.fork()
cluster.on("exit")
PM2
pm2 start server.js -i max
PM2 internally uses clustering and process management.
Benefits:
Auto Restart
Monitoring
Logs
Zero Downtime Deploy
Cluster Management
For production, most companies use:
Nginx
|
PM2 Cluster
|
Node.js
|
Redis
|
MongoDB/MySQL
Interview Answer
The Node.js Cluster Module allows a Node.js application to utilize multiple CPU cores by creating worker processes. A master process forks workers equal to the number of CPU cores and distributes incoming requests among them. Each worker runs its own event loop and memory space. Cluster improves throughput, CPU utilization, and fault tolerance, but shared state must be stored externally in systems like Redis, MongoDB, or MySQL. For production deployments, PM2 cluster mode is often preferred because it simplifies worker management and automatic restarts.
