Discover how spreading work across workers can make your app lightning fast and crash-proof!
Why Load balancing between workers in Node.js? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine you have a busy web server handling many user requests at once. You try to manage all requests with a single process, but it quickly gets overwhelmed and slows down.
Handling all tasks in one process causes delays and crashes because it can only do one thing at a time. Manually splitting tasks between processes is tricky and error-prone, leading to uneven work and wasted resources.
Load balancing between workers automatically spreads tasks evenly across multiple processes. This keeps the server fast and stable by making sure no single worker is overloaded.
const http = require('http'); http.createServer((req, res) => { // single process handles all requests res.end('Hello World'); }).listen(3000);
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(); } } else { http.createServer((req, res) => { res.end('Hello World'); }).listen(3000); }
It enables your application to handle many users smoothly by using all CPU cores efficiently.
A popular online store uses load balancing between workers to serve thousands of shoppers at the same time without slowing down or crashing.
Single-process servers struggle under heavy load.
Manual task splitting is complex and inefficient.
Load balancing spreads work evenly, improving speed and reliability.
Practice
cluster module in Node.js for load balancing?Solution
Step 1: Understand the role of the cluster module
The cluster module allows Node.js to create multiple worker processes that share the same server port.Step 2: Identify the purpose of load balancing
Load balancing means distributing incoming requests evenly across workers to use CPU cores efficiently.Final Answer:
To spread incoming requests across multiple CPU cores using worker processes -> Option AQuick Check:
Load balancing = spreading requests across workers [OK]
- Thinking cluster creates a single-threaded server
- Confusing load balancing with database management
- Assuming cluster compresses data for memory optimization
Solution
Step 1: Recall the cluster API properties
Node.js cluster module providesisMasterandisWorkerboolean properties to identify process roles.Step 2: Identify the correct property for master check
cluster.isMasteris true if the process is the master, so the condition should use this.Final Answer:
if (cluster.isMaster) { /* master code */ } -> Option CQuick Check:
Master check uses cluster.isMaster [OK]
- Using cluster.isWorker to check for master
- Using non-existent properties like cluster.master
- Confusing cluster.worker with cluster.isWorker
const cluster = require('cluster');
const http = require('http');
if (cluster.isMaster) {
cluster.fork();
cluster.fork();
} else {
http.createServer((req, res) => {
res.end(`Worker ${process.pid} handled request`);
}).listen(8000);
}
What will happen when you send multiple requests to port 8000?Solution
Step 1: Understand cluster.fork() behavior
Calling cluster.fork() creates worker processes that share the same server port.Step 2: Analyze request handling in workers
Both workers listen on port 8000 and Node.js load balances requests between them automatically.Final Answer:
Requests will be handled by both worker processes, distributing load -> Option AQuick Check:
Multiple workers share port and balance requests [OK]
- Thinking only one worker handles all requests
- Assuming master handles requests directly
- Believing server crashes due to port sharing
const cluster = require('cluster');
if (cluster.isMaster) {
cluster.fork();
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
});
} else {
throw new Error('Crash');
}Solution
Step 1: Check the exit event handler
The master listens for 'exit' but only logs the death, it does not fork a new worker.Step 2: Identify missing restart logic
To restart workers after crash, the master must callcluster.fork()inside the exit event handler.Final Answer:
The master does not fork a new worker after exit event -> Option DQuick Check:
Restart requires forking new worker on exit [OK]
- Assuming worker error handling restarts process
- Thinking cluster import affects restart
- Believing exit event is attached incorrectly
Solution
Step 1: Fork workers equal to CPU cores in master
if (cluster.isMaster) { const cpuCount = require('os').cpus().length; for (let i = 0; i < cpuCount; i++) { cluster.fork(); } cluster.on('exit', (worker) => { console.log(`Worker ${worker.process.pid} died, restarting...`); cluster.fork(); }); } else { require('http').createServer((req, res) => { res.end(`Handled by worker ${process.pid}`); }).listen(3000); } correctly usesos.cpus().lengthto fork that many workers in the master process.Step 2: Restart workers on exit event in master
if (cluster.isMaster) { const cpuCount = require('os').cpus().length; for (let i = 0; i < cpuCount; i++) { cluster.fork(); } cluster.on('exit', (worker) => { console.log(`Worker ${worker.process.pid} died, restarting...`); cluster.fork(); }); } else { require('http').createServer((req, res) => { res.end(`Handled by worker ${process.pid}`); }).listen(3000); } listens to the 'exit' event on cluster and forks a new worker to replace the dead one.Step 3: Worker creates HTTP server listening on port 3000
if (cluster.isMaster) { const cpuCount = require('os').cpus().length; for (let i = 0; i < cpuCount; i++) { cluster.fork(); } cluster.on('exit', (worker) => { console.log(`Worker ${worker.process.pid} died, restarting...`); cluster.fork(); }); } else { require('http').createServer((req, res) => { res.end(`Handled by worker ${process.pid}`); }).listen(3000); }'s else block creates the server in workers, which is correct for load balancing.Final Answer:
Forks workers across all CPU cores and automatically restarts workers if they crash -> Option BQuick Check:
Fork all CPUs + restart on exit = if (cluster.isMaster) { const cpuCount = require('os').cpus().length; for (let i = 0; i < cpuCount; i++) { cluster.fork(); } cluster.on('exit', (worker) => { console.log(`Worker ${worker.process.pid} died, restarting...`); cluster.fork(); }); } else { require('http').createServer((req, res) => { res.end(`Handled by worker ${process.pid}`); }).listen(3000); } [OK]
- Not forking all CPU cores
- Not restarting workers after crash
- Forking workers inside worker process
- Attaching exit listener inside worker instead of master
