Cluster

One Process Per CPU — Built-In Horizontal Scaling

Cluster

cluster forks your script across multiple processes, all sharing the same listening port.

3 min read Level 2/5 #nodejs#cluster#scaling
What you'll learn
  • Fork workers per CPU
  • Share a server port across processes
  • Decide when to cluster

A single Node process runs one event loop. To use all the cores on a machine, you run multiple processes. node:cluster automates this — and lets them share a server port.

A Clustered Server

import cluster from "node:cluster";
import { cpus } from "node:os";
import { createServer } from "node:http";

if (cluster.isPrimary) {
  const n = cpus().length;
  console.log(`primary spawning ${n} workers`);
  for (let i = 0; i < n; i++) cluster.fork();

  cluster.on("exit", (worker) => {
    console.log(`worker ${worker.process.pid} died — restarting`);
    cluster.fork();
  });
} else {
  createServer((req, res) => {
    res.end(`served by pid ${process.pid}`);
  }).listen(3000);
}

All workers bind to port 3000. The OS distributes incoming connections round-robin. Each handles requests on its own event loop.

When to Cluster

  • You’re CPU-bound on a single core
  • You have multi-core hardware
  • You can tolerate the per-process memory cost (a Node process is ~50MB; 8 workers = ~400MB)

For IO-bound workloads (most APIs), a single process with async IO scales fine. Don’t cluster blindly.

Modern Alternative

For real production, you usually run multiple Node containers behind a load balancer (Nginx, Cloudflare, Kubernetes). That gives you cluster’s benefit plus zero-downtime deploys, isolated failures, and easy horizontal scaling across machines.

Cluster is most useful for single-server setups (VPS, bare metal) where adding more containers is overkill.

pm2 and node:cluster

pm2 (a popular process manager) uses cluster mode by default — no manual code needed:

pm2 start app.mjs -i max   # one per core
Timers →