Deploying Node.js with PM2: Process Guarding and Cluster Mode
Running a Node.js app with plain node app.js in production means the service dies whenever the process crashes or the server reboots. PM2 is the process manager built to solve exactly that: it keeps the app running in the background, restarts it after crashes, boots it automatically, and can use cluster mode to fully utilize multiple CPU cores.
1. Installation and Startup
PM2 is installed globally via npm:
npm install -g pm2
pm2 start app.js --name my-api
pm2 start daemonizes and monitors the process in the background. Common commands:
pm2 list # view status of all processes
pm2 logs my-api # view logs
pm2 monit # real-time terminal monitoring dashboard
pm2 restart my-api # restart
pm2 stop my-api # stop
pm2 delete my-api # remove from PM2
Verify the install with pm2 -v; if your company network uses an npm mirror, configure the registry first to avoid install timeouts.
2. Cluster Mode: Making the Most of Multiple Cores
The default fork mode is a single process that uses only one CPU core. For HTTP/WS applications, use cluster mode to spawn multiple processes based on CPU count; PM2's built-in load balancer distributes connections automatically:
pm2 start app.js -i max # start one process per available CPU
pm2 scale app +3 # dynamically add 3 processes
How to choose between the two modes:
| Aspect | fork mode | cluster mode |
|---|---|---|
| Process count | 1 | spawned per CPU core |
| CPU usage | single core | multiple cores |
| Session stickiness | n/a | built-in load balancing |
| Best for | cron jobs, CLI tools | HTTP/WebSocket services |
For production, declaring this in a config file is recommended:
// ecosystem.config.js
module.exports = {
apps: [{
name: "api",
script: "./src/server.js",
instances: "max", // cluster mode, process count = CPU cores
exec_mode: "cluster",
max_memory_restart: "300M", // auto-restart above 300M
env: {
NODE_ENV: "production",
PORT: 3000
},
time: true // timestamp logs
}]
};
pm2 start ecosystem.config.js
max_memory_restart is very useful: it restarts a process automatically on memory leaks, buying time to investigate. For sensitive config, prefer an environment-variable file and combine it with environment variables and secret management — do not hard-code database passwords in the config.
3. Boot Persistence: pm2 startup and pm2 save
After a server reboot, PM2 needs to restore all processes. Two steps solve it:
pm2 startup # generate and install a startup script (it will prompt for a sudo command)
pm2 save # save the current process list, restored automatically at boot
pm2 startup generates the appropriate systemd unit for your system so PM2 and its managed processes start automatically at boot. Important: re-run pm2 save every time you add or remove a process, otherwise the next reboot restores the old process list.
4. Zero-Downtime Reload
A normal pm2 restart is "stop then start" and causes a brief interruption. For network applications in cluster mode, use pm2 reload for rolling restarts one process at a time, achieving zero downtime:
pm2 reload all # gracefully reload all processes
PM2 brings up the new process first and only switches over once old connections drain, which makes it ideal to call from the deployment script of an automated CI/CD deployment. For more systematic strategies see zero-downtime deployment strategies.
5. Log Management
PM2 writes stdout/stderr to logs by default and supports rotation:
pm2 logs my-api --lines 200 # view the last 200 lines
pm2 install pm2-logrotate # install the log rotation module
In production, consider feeding logs to a collection system and handling them together with ELK log analysis or monitoring and alerting.
6. Process Status Monitoring
pm2 monit provides real-time CPU/memory monitoring; pm2 describe <id> shows detailed process info. A sharply rising restart count is usually a signal of code crashes or memory leaks, and you can collect metrics with Prometheus and Grafana. Treat PM2 monitoring as the first line of defense: when something looks wrong, check pm2 monit and the restart count before diving into system-level investigation — it saves a lot of time.
Common Questions
- My processes disappeared after a reboot? Most likely
pm2 savewas never run, or the startup script was not installed. Re-runpm2 save, thenpm2 startuponce more. - Why does memory usage double in cluster mode? That is expected — each instance has its own memory space, so N instances roughly equal single-instance memory × N. Factor total memory in when sizing
max_memory_restart. - What if the port is taken? In cluster mode instances share one port by default, handled by PM2's built-in load balancer; if startup reports EADDRINUSE, check for leftover processes or an accidental fork mode.
7. A Complete Deploy Script
String the commands above together and you have a concise release script:
# deploy.sh
cd /srv/app
git pull origin main
npm ci --production
pm2 reload ecosystem.config.js # zero downtime
pm2 save # save the latest process list
On the first deploy run pm2 start ecosystem.config.js; afterwards, every release is just pm2 reload plus pm2 save.
8. Pairing with an Nginx Reverse Proxy
PM2 manages the Node process itself; external exposure should be handled by an Nginx reverse proxy: Nginx listens on 80/443, terminates TLS and forwards to the local port PM2 is listening on. For the non-LNMP Node stack see the Node.js Express guide; if your app also runs background job queues, manage them together with the background job queue guide. Placing the reverse proxy at the edge has another benefit: no matter how the Node processes scale or restart, the external address never changes, and clients and search engines never notice internal churn.
16IDC Note
PM2's value is solving the "liveness" problem of Node production processes at a tiny learning cost: guarding, restarting, boot persistence, clustering, logging and monitoring all in one tool. For independent sites and small teams, the pm2 start + pm2 startup + pm2 save triple makes the app run reliably in production, and combined with an Nginx reverse proxy and automated CI/CD it forms a complete, lightweight Node go-live solution.
Source: https://pm2.keymetrics.io/docs/usage/quick-start/ , https://pm2.keymetrics.io/docs/usage/process-management/
Reference: PM2 cluster mode docs https://pm2.keymetrics.io/docs/usage/cluster-mode/