Suggest an editImprove this articleRefine the answer for “What is the cluster module?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)`cluster` is a built-in Node.js module that runs several copies of the same application (workers), distributing incoming requests across them on one shared port using Round Robin. **Key point:** each worker is a separate process with its own event loop, so one crashing doesn't affect the others.Shown above the full answer for quick recall.Answer (EN)Image## What `cluster` is > `cluster` is a built-in Node.js module > that lets you run **several copies of the same application (workers)**, > distributing incoming requests between them on **one shared port**. In other words: > `cluster` makes Node.js multi-process, creating a "herd" of workers, > where each worker is a separate Node.js process with its own event loop. ## Why `cluster` is needed By default, Node.js runs **on a single thread** and uses **only one CPU core**. If your server has 8 cores, without clustering, 7 of them sit idle. **The fix:** - `cluster` lets you run **several workers** (one per CPU core), - and **spread the load** across them automatically. ## 1. A simple picture of how it works ```javascript ┌─────────────────────┐ │ Master Process │ ← listens on a port (e.g. 3000) └────────┬────────────┘ │ ┌───────┴────────┬────────┬────────┐ │ │ │ │ ▼ ▼ ▼ ▼ Worker 1 Worker 2 Worker 3 Worker 4 (port 3000) (port 3000) ... ``` - Every worker listens on **the same port**. - Node.js (through the master) **balances requests** between them (Round Robin). - Each worker is a **separate process**, so one crashing doesn't affect the rest. ## 2. An example of using `cluster` **server.js** ```javascript const cluster = require('cluster'); const http = require('http'); const os = require('os'); if (cluster.isPrimary) { // The primary process const numCPUs = os.cpus().length; console.log(`Primary process ${process.pid}. Starting ${numCPUs} workers...`); // Create workers, one per core for (let i = 0; i < numCPUs; i++) { cluster.fork(); } // If a worker dies, create a new one cluster.on('exit', (worker) => { console.log(`Worker ${worker.process.pid} exited. Restarting...`); cluster.fork(); }); } else { // Workers (handle requests) http.createServer((req, res) => { res.end(`Response from worker ${process.pid}\n`); }).listen(3000); console.log(`Worker ${process.pid} started`); } ``` What happens: - The primary process (`isPrimary`) creates workers via `cluster.fork()`. - Each worker is a **new Node.js process**. - Every worker listens on the same port (`3000`). - Requests get distributed among them automatically. ## 3. How balancing works Node.js implements **Round-Robin load balancing** itself: - The primary process accepts connections on the main port. - Then it **evenly distributes** them among workers. That means: > you don't need to set up Nginx or an external load balancer, > it's all handled "out of the box" at the Node.js level. ## 4. Events on the `cluster` module | Event | Fires where | What it does | |---|---|---| | `fork` | master | A new worker was created | | `online` | master | The worker is running | | `listening` | master | The worker is listening on the port | | `exit` | master | The worker exited | | `message` | master ↔ worker | A message between processes | Example: ```javascript cluster.on('online', (worker) => console.log(`Worker ${worker.process.pid} is ready`)); ``` ## 5. Exchanging data between master and worker You can pass data between processes (like in `child_process`): **master** ```javascript worker.send({ msg: 'Hello from the master!' }); ``` **worker** ```javascript process.on('message', (data) => { console.log('Received:', data); process.send({ reply: 'Hello back!' }); }); ``` ## 6. `cluster` vs `worker_threads` | Criterion | `cluster` | `worker_threads` | |---|---|---| | Unit of execution | Process | Thread | | Memory | Separate | Shared (via SharedArrayBuffer) | | Event Loop | One per unit | One per unit | | Good for | Web servers, APIs, scaling | Computational tasks | | Data exchange | Via IPC (JSON) | Via SharedArrayBuffer, Atomics | | Restarting workers | Automatic | Manual | | Error isolation | Full | Partial | In other words: - `cluster` is a **multi-process architecture** for **CPU-bound load**. - `worker_threads` is a **multi-threaded model** for **heavy computation** inside a single process. ## 7. A real-world example **An Express server with clustering:** ```javascript const cluster = require('cluster'); const os = require('os'); const express = require('express'); if (cluster.isPrimary) { const numCPUs = os.cpus().length; for (let i = 0; i < numCPUs; i++) cluster.fork(); } else { const app = express(); app.get('/', (req, res) => res.send(`Handled by worker ${process.pid}`)); app.listen(3000, () => console.log(`Worker ${process.pid} started`)); } ``` Now every worker handles part of the requests → the app scales automatically. ## 8. Advantages and drawbacks | Advantages | Drawbacks | |---|---| | Uses every CPU core | Each worker is a separate process (memory ×N) | | Simple setup | Harder to debug | | High resilience | No shared memory (only through IPC) | | Automatic recovery | TCP-level balancing (can be a constraint with WebSocket) | ## Summary | Criterion | Description | |---|---| | Purpose | Scaling a Node.js app across every CPU core | | Implementation | Several Node.js processes (workers) | | Managed by | The primary process (master) | | Load distribution | Round Robin | | Data exchange | IPC (`worker.send`, `process.on('message')`) | | Ideal for | Servers, APIs, microservices | **Conclusion:** > The `cluster` module lets Node.js use **every processor core**, > creating several independent processes (workers) > that **jointly serve requests** on one port. > > It's a built-in, out-of-the-box **scaling and resilience mechanism** for Node.js servers.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.