Skip to main content

What is the cluster module?

What cluster is

cluster is a built-in Node.js module that lets you run several copies of the same application (workers), distributing incoming requests between them on one shared port.

In other words:

cluster makes Node.js multi-process, creating a "herd" of workers, where each worker is a separate Node.js process with its own event loop.

Why cluster is needed

By default, Node.js runs on a single thread and uses only one CPU core. If your server has 8 cores, without clustering, 7 of them sit idle.

The fix:

  • cluster lets you run several workers (one per CPU core),
  • and spread the load across them automatically.

1. A simple picture of how it works

javascript
┌─────────────────────┐ Master Process │ ← listens on a port (e.g. 3000) └────────┬────────────┘ ┌───────┴────────┬────────┬────────┐ │ │ │ │ ▼ ▼ ▼ ▼ Worker 1 Worker 2 Worker 3 Worker 4 (port 3000) (port 3000) ...
  • Every worker listens on the same port.
  • Node.js (through the master) balances requests between them (Round Robin).
  • Each worker is a separate process, so one crashing doesn't affect the rest.

2. An example of using cluster

server.js

javascript
const cluster = require('cluster'); const http = require('http'); const os = require('os'); if (cluster.isPrimary) { // The primary process const numCPUs = os.cpus().length; console.log(`Primary process ${process.pid}. Starting ${numCPUs} workers...`); // Create workers, one per core for (let i = 0; i < numCPUs; i++) { cluster.fork(); } // If a worker dies, create a new one cluster.on('exit', (worker) => { console.log(`Worker ${worker.process.pid} exited. Restarting...`); cluster.fork(); }); } else { // Workers (handle requests) http.createServer((req, res) => { res.end(`Response from worker ${process.pid}\n`); }).listen(3000); console.log(`Worker ${process.pid} started`); }

What happens:

  • The primary process (isPrimary) creates workers via cluster.fork().
  • Each worker is a new Node.js process.
  • Every worker listens on the same port (3000).
  • Requests get distributed among them automatically.

3. How balancing works

Node.js implements Round-Robin load balancing itself:

  • The primary process accepts connections on the main port.
  • Then it evenly distributes them among workers.

That means:

you don't need to set up Nginx or an external load balancer, it's all handled "out of the box" at the Node.js level.

4. Events on the cluster module

EventFires whereWhat it does
forkmasterA new worker was created
onlinemasterThe worker is running
listeningmasterThe worker is listening on the port
exitmasterThe worker exited
messagemaster ↔ workerA message between processes

Example:

javascript
cluster.on('online', (worker) => console.log(`Worker ${worker.process.pid} is ready`));

5. Exchanging data between master and worker

You can pass data between processes (like in child_process):

master

javascript
worker.send({ msg: 'Hello from the master!' });

worker

javascript
process.on('message', (data) => { console.log('Received:', data); process.send({ reply: 'Hello back!' }); });

6. cluster vs worker_threads

Criterionclusterworker_threads
Unit of executionProcessThread
MemorySeparateShared (via SharedArrayBuffer)
Event LoopOne per unitOne per unit
Good forWeb servers, APIs, scalingComputational tasks
Data exchangeVia IPC (JSON)Via SharedArrayBuffer, Atomics
Restarting workersAutomaticManual
Error isolationFullPartial

In other words:

  • cluster is a multi-process architecture for CPU-bound load.
  • worker_threads is a multi-threaded model for heavy computation inside a single process.

7. A real-world example

An Express server with clustering:

javascript
const cluster = require('cluster'); const os = require('os'); const express = require('express'); if (cluster.isPrimary) { const numCPUs = os.cpus().length; for (let i = 0; i < numCPUs; i++) 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`)); }

Now every worker handles part of the requests → the app scales automatically.

8. Advantages and drawbacks

AdvantagesDrawbacks
Uses every CPU coreEach worker is a separate process (memory ×N)
Simple setupHarder to debug
High resilienceNo shared memory (only through IPC)
Automatic recoveryTCP-level balancing (can be a constraint with WebSocket)

Summary

CriterionDescription
PurposeScaling a Node.js app across every CPU core
ImplementationSeveral Node.js processes (workers)
Managed byThe primary process (master)
Load distributionRound Robin
Data exchangeIPC (worker.send, process.on('message'))
Ideal forServers, APIs, microservices

Conclusion:

The cluster module lets Node.js use every processor core, creating several independent processes (workers) that jointly serve requests on one port.

It's a built-in, out-of-the-box scaling and resilience mechanism for Node.js servers.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.