Scale a network server across processes
An HTTP or TCP service needs to use multiple CPU cores while retaining one public listening port.
Node.js · Module
The cluster module runs multiple Node.js processes that share server ports, allowing incoming connections and application work to be distributed among workers. A primary process creates and supervises workers, which communicate with it through IPC.
The cluster module creates multiple Node.js processes that share server ports. A primary process forks workers, and the cluster machinery distributes incoming connections among them; workers communicate with the primary through IPC and can be inspected through cluster worker objects.
import cluster from 'node:cluster';
cluster.fork([env]);
cluster.on('exit', listener);const cluster = require('node:cluster');
const http = require('node:http');
const process = require('node:process');
if (cluster.isPrimary) {
for (let i = 0; i < 2; 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);
}Starts two worker processes that share port 8000; each worker handles HTTP requests and the primary reports worker exits.
An HTTP or TCP service needs to use multiple CPU cores while retaining one public listening port.
A primary process should replace workers that terminate unexpectedly.
Independent worker processes need IPC while serving the same network endpoint.
The cluster module lets one application run multiple Node.js processes that share server ports. The primary process creates workers, and incoming connections can be distributed among those workers.
Follow-up: How are workers created? They are spawned through child_process.fork(), which also provides IPC and allows server handles to be passed between the primary and workers.
The default strategy is round-robin on every platform except Windows. The primary listens, accepts connections, and distributes them to workers, while another supported strategy lets the operating system distribute connections.
Follow-up: Where can a worker be found programmatically? In the primary, use cluster.workers; inside a worker, use cluster.worker.
cluster.isPrimary identifies whether the current process is the primary, while cluster.isWorker identifies a worker process. A primary commonly forks workers and supervises their lifecycle; workers run the application server.
Follow-up: What event helps supervise terminated workers? The cluster 'exit' event fires when a worker exits, allowing an application to decide whether to create a replacement.
child_process.fork()cluster.isPrimarycluster.isWorkercluster.workerscluster.workerWorker'exit' eventserver.listen()