How to Scale Node.js Across CPU Cores with the Cluster Module
By default a Node.js process runs on a single CPU core, so on a multi-core server you are leaving most of the machine idle. The cluster module fixes that by forking multiple worker processes that share the same port — letting one app use every core and handle far more concurrent traffic.
How clustering works
A primary process forks several workers — typically one per CPU core. The primary shares the listening socket, and incoming connections are distributed across the workers (round-robin on Linux). Each worker is a full Node process with its own event loop and memory.
A minimal example
const cluster = require('node:cluster'); const os = require('node:os');
if (cluster.isPrimary) { for (const c of os.cpus()) cluster.fork(); }
else { require('./server'); }
Now you have one worker per core, all serving the same port.
The catch: shared state
Workers do not share memory. So in-memory sessions, caches or counters live separately in each worker. The fixes:
- Store shared state externally — use Redis for sessions and caches.
- Make workers stateless so any worker can serve any request.
The easier route in production: PM2
Rather than writing cluster code by hand, PM2's cluster mode manages workers for you with a single flag, plus zero-downtime reloads. For most deployments this is the practical choice — see running Node.js in production with PM2. For heavy CPU work specifically, also consider worker threads.
Frequently asked questions
Cluster module or PM2 — which should I use?
PM2 in production, because it handles forking, restarts and zero-downtime reloads for you. Use the raw cluster module when you need fine-grained control or are learning how it works.
Does clustering help with CPU-bound work?
It spreads separate requests across cores, but a single heavy request still blocks its own worker. For CPU-intensive work within a request, use worker threads instead.
How many workers should I run?
Commonly one per CPU core, but benchmark for your workload — see load-testing your API. More workers is not always faster, and each uses memory.
Was this article helpful?