Mastering Node.js Multi‑Process Architecture: Fork, Cluster, and IPC Explained

This article explains how Node.js handles processes, demonstrates creating child processes with fork, illustrates inter‑process communication (IPC) using send and message events, explores handle passing and shared ports, and shows how to build robust clusters with the built‑in cluster module.

ELab Team
ELab Team
ELab Team
Mastering Node.js Multi‑Process Architecture: Fork, Cluster, and IPC Explained

Process

In an operating system a process is a running application. Tools like Activity Monitor or Task Manager list each active process.

Multi‑process

Copying a process

Node.js provides the child_process module and the child_process.fork() function to duplicate a process.

Example files:

worker.js

const http = require('http');

http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello NodeJS!
');
}).listen(Math.round((1 + Math.random()) * 2000), '127.0.0.1');

master.js

const { fork } = require('child_process');
const { cpus } = require('os');

cpus().map(() => {
  fork('./worker.js');
});

Running node master.js and checking with ps aux | grep worker.js shows that, ideally, the number of processes equals the number of CPU cores, each using one core.

This is the classic Master‑Worker (master‑slave) pattern.

Forking processes is expensive; Node.js uses an event‑driven single‑threaded model to achieve high concurrency while leveraging multiple processes for CPU‑bound work.

Creating child processes

The child_process module offers four methods:

child_process.spawn(command, args)

child_process.exec(command, options)

child_process.execFile(file, args[, callback])

child_process.fork(modulePath, args)

Comparison:

The last three are extensions of spawn().

Inter‑process communication (IPC)

In Node.js a child process object uses send() to transmit data to the parent, and the parent listens for the message event to receive data.

Example files:

parent.js

const { fork } = require('child_process');
const sender = fork(__dirname + '/child.js');

sender.on('message', msg => {
  console.log('Parent received:', msg);
});

sender.send('Hey! Child');

child.js

process.on('message', msg => {
  console.log('Child received:', msg);
});

process.send('Hey! Parent');

Running node parent.js produces the communication shown below:

IPC concept

IPC (inter‑process communication) lets separate processes share resources and coordinate work.

Before creating a child, the parent creates an IPC channel, passes the file descriptor via the environment variable NODE_CHANNEL_FD, and the child connects to the channel on startup.

Handle passing

A handle is a reference that contains a file descriptor pointing to a resource.

When multiple processes need to listen on the same port, the master can send the server handle to each worker, allowing all workers to share the port without extra descriptors.

Sending a handle is done by passing it as the optional second argument to send(). Supported handle types are:

net.Socket

net.Server

net.Native

dgram.Socket

dgram.Native

Handle serialization

Only the handle metadata is sent; the actual object is not transferred. The message is JSON‑stringified, transmitted as a string, and reconstructed with JSON.parse on the receiving side.

Shared port listening

Because each worker receives the same server handle, they can all accept connections on the same port without conflict.

Cluster

According to the Egg.js documentation, a cluster runs multiple processes on a server, each executing the same code and able to listen on a single port.

The master process starts other processes and acts as a “foreman”.

Worker processes handle the actual requests.

The number of workers usually matches the CPU core count to fully utilize resources.

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('exit', function (worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {
  http.createServer(function (req, res) {
    res.writeHead(200);
    res.end('hello world
');
  }).listen(8000);
}

The cluster module internally uses child_process and net. It creates a TCP server in the master, passes the server socket descriptor to workers, and exposes events such as fork, online, listening, disconnect, exit, and setup to improve stability.

Process daemon (守护)

Uncaught exceptions

If a worker throws an uncaught exception, it should exit gracefully. The master can listen to process.on('uncaughtException', handler), close the worker’s TCP servers, disconnect the IPC channel, and immediately fork a new worker to keep the pool size constant.

+---------+          +---------+
|  Worker |          |  Master |
+---------+          +----+----+
     | uncaughtException   |
     +------------+        |
     |            |        |
     |<----------+        |
     |                     +---------+
     |                     |  Worker |
     |                     +----+----+
     |        disconnect   |   fork a new worker   |
     +--------------------> + ---------------------> |
     |            wait... |                     |
     |            exit    |                     |
     +--------------------> |                     |

OOM or system crashes

When a process crashes due to OOM or a system error, there is no chance to continue; the master simply forks a new worker.

References

《深入浅出 Node.js》

Node.js Chinese Documentation

Egg.js Official Documentation

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Node.jsmulti-processClusterIPCprocesschild_process
ELab Team
Written by

ELab Team

Sharing fresh technical insights

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.