Scale a network server across processes
Run several server processes behind one listening port.
Node.js · Module
The node:cluster module creates multiple Node.js worker processes that can share server ports. A primary process manages workers and can distribute incoming connections among them.
The cluster module starts multiple child processes from one application. A primary process creates workers with fork(), while workers run server code and share a listening port; the primary can distribute connections, and processes communicate through IPC.
import cluster from 'node:cluster';
cluster.fork();import cluster from 'node:cluster';
import http from 'node:http';
import process from 'node:process';
if (cluster.isPrimary) {
const workers = 2;
for (let i = 0; i < workers; i++) cluster.fork();
cluster.on('exit', (worker) => {
console.log(`worker ${worker.process.pid} exited`);
});
} else {
http.createServer((_req, res) => {
res.end(`handled by ${process.pid}\n`);
}).listen(8000);
}Run with Node.js; the primary creates two workers, and each worker serves the same HTTP port.
Run several server processes behind one listening port.
Keep a primary process responsible for worker lifecycle management.
Exchange control or application messages between the primary and workers.
The primary process manages the cluster and creates workers, while workers execute the server logic. Workers are child processes created through fork() and can communicate with the primary using IPC.
Follow-up: How are incoming connections distributed? By default, the primary accepts connections and distributes them round-robin, except that Windows uses a different default strategy.
The cluster module lets multiple Node.js processes share server ports. This allows several application instances to handle connections through one listening port.
Follow-up: Why can this improve throughput? It lets a server use multiple processes and therefore distribute network workload across available application execution capacity.
A Worker object represents a worker process. The primary can access workers through cluster.workers, while code running in a worker can access its own worker through cluster.worker.
Follow-up: How can a primary react to worker termination? It can listen for the cluster worker exit event and decide whether to create a replacement.
cluster.fork()cluster.isPrimarycluster.isWorkercluster.workerscluster.workercluster.schedulingPolicycluster.SCHED_RRWorker