Learn How to Scale Node.js Applications with Nginx Load Balancing and Clustering
Node.js is fast and lightweight, but scaling it for production traffic requires smart strategies. This guide walks you through setting up Nginx as a load balancer and enabling clustering in your Node.js app to fully utilize multi-core systems.
Why You Need to Scale Node.js
- Node.js runs on a single thread by default.
- One crash or CPU-intensive task can block requests.
- Modern servers have multiple CPU cores—let’s use them!
By using clustering, we create multiple Node.js processes. With Nginx, we distribute incoming traffic evenly across them.
Prerequisites
- Ubuntu/Debian-based Linux server (or local VM)
- Node.js app (basic Express server)
- Nginx installed
- PM2 (optional, for process management)
Step 1: Add Clustering to Your Node.js App
Create or update your server.js
:
const cluster = require('cluster');
const os = require('os');
const express = require('express');
const numCPUs = os.cpus().length;
if (cluster.isMaster) {
console.log(`Master process ${process.pid} is running`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code) => {
console.log(`Worker ${worker.process.pid} died. Restarting...`);
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`);
});
}
What this does:
- Fork one process per CPU core.
- Each worker handles incoming traffic.
- If a worker crashes, it respawns automatically.
Step 2: Test Locally
Run the app:
node server.js
Visit http://localhost:3000 in multiple tabs. You’ll see different worker PIDs serving each request (randomly).
Step 3: Set Up Nginx as Load Balancer
Install Nginx
sudo apt updatesudo apt install nginx -y
Configure Nginx
Edit Nginx config:
sudo nano /etc/nginx/sites-available/node-app
Example
upstream node_cluster {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
}
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://node_cluster;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Enable Config
sudo ln -s /etc/nginx/sites-available/node-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Step 4: Run Multiple Node.js Instances on Different Ports
You can clone your app and run it with different port numbers:
PORT=3000 node server.js &
PORT=3001 node server.js &
PORT=3002 node server.js &
PORT=3003 node server.js &
Or use PM2 for process management:
npm install -g pm2
pm2 start server.js -i 4 # Automatically spawns 4 processes
Step 5: Test Load Balancing
Visit your domain or IP (e.g., http://yourdomain.com) multiple times. Nginx will route requests to different backend ports, showing different worker PIDs.
Bonus Tips
- Enable SSL via Let's Encrypt + Certbot
- Monitor using PM2 Plus or Prometheus
- Auto-restart with PM2 on crashes
0 Comments