Node.js8 min read

Node.js Clustering for Multi-Core CPUs

Understand Node.js clustering. Use all CPU cores to handle more traffic.

Sarah Chen
December 19, 2025
0.0k0

Node.js Clustering

The Problem: Single-Threaded Limitation

Node.js runs on a single thread. This means:

  • Your app uses only 1 CPU core
  • On a 4-core CPU, you're using 25% of available power
  • Other 3 cores sit idle doing nothing
  • One heavy request blocks others
4-Core CPU:
Core 1: ████████ (Node.js running here)
Core 2: -------- (idle)
Core 3: -------- (idle)
Core 4: -------- (idle)

Result: 75% of CPU wasted!

What is Clustering?

Clustering creates multiple Node.js processes (workers) that:

  • Share the same server port
  • Each runs on a different CPU core
  • Work independently
  • Handle requests in parallel
Master Process (manages workers)
  ├── Worker 1 (Core 1) → Handles Request A
  ├── Worker 2 (Core 2) → Handles Request B
  ├── Worker 3 (Core 3) → Handles Request C
  └── Worker 4 (Core 4) → Handles Request D

All 4 requests processed simultaneously!

How Clustering Works

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

if (cluster.isMaster) {
  const numCPUs = os.cpus().length;
  console.log(`Master process running. CPU cores: ${numCPUs}`);
  
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  
  cluster.on('exit', (worker) => {
    console.log(`Worker ${worker.process.pid} died`);
    cluster.fork();
  });
  
} else {
  const app = express();
  
  app.get('/', (req, res) => {
    res.send(`Handled by worker ${process.pid}`);
  });
  
  app.listen(3000);
  console.log(`Worker ${process.pid} started`);
}

Explanation:

  1. Master process checks cluster.isMaster
  2. Master creates workers with cluster.fork()
  3. Worker processes run your Express app
  4. OS automatically distributes requests
  5. If worker crashes, master restarts it

Benefits of Clustering

1. Better Performance

Without Clustering: 100 req/sec
With Clustering (4 cores): 380 req/sec

2. Fault Tolerance
If one worker crashes, others keep running.

3. Zero Downtime Restarts
Restart workers one by one.

4. Full CPU Utilization
Use all cores instead of just one.

Using PM2 (Production Ready)

PM2 is a process manager that handles clustering automatically.

npm install -g pm2

pm2 start app.js -i max

pm2 list
pm2 logs
pm2 monit

-i max = Use all CPU cores

No code changes needed! PM2 handles everything.

Critical Issue: Shared State

let counter = 0;

app.get('/', (req, res) => {
  counter++;
  res.send(`Count: ${counter}`);
});

Problem: Each worker has its own counter variable!

Worker 1: counter = 5
Worker 2: counter = 3
Worker 3: counter = 7
Worker 4: counter = 2

Total should be 17, but each worker shows different count!

Solution: Use Redis for shared state

const redis = require('redis');
const client = redis.createClient();

app.get('/', async (req, res) => {
  const count = await client.incr('counter');
  res.send(`Count: ${count}`);
});

Now all workers share the same counter in Redis.

When to Use Clustering

✅ Use When:

  • CPU-intensive operations
  • High traffic applications
  • Need fault tolerance
  • Multiple CPU cores available

❌ Don't Use When:

  • I/O-bound operations (database queries)
  • Single-core server
  • Shared memory needed (use Worker Threads instead)

Key Takeaway

Clustering multiplies your app's capacity by using all CPU cores. Use PM2 in production for automatic management. Workers don't share memory - use Redis for shared state. Each worker is independent, so if one crashes, others keep serving requests.

#Node.js#Clustering#Performance#Scalability