Skip to content

Node.js PM2 Process Manager — Complete Guide to Production Node.js Deployment

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Node.js PM2 Process Manager. We cover key concepts, practical examples, and best practices to help you master this topic.

PM2 process manager keeps Node.js applications running in production with cluster mode, automatic restarts, zero-downtime reloads, built-in monitoring, and log management.

What You'll Learn

By the end of this tutorial, you'll install and configure PM2, run in cluster mode, perform zero-downtime deployments, monitor application health, manage logs, and set up startup scripts.

Why PM2 Matters

Production Node.js processes crash. Without a process manager, the application stays down until manually restarted. PM2 handles crashes, scales across CPUs, and provides monitoring.

Real-World Use

A Node.js API server runs in cluster mode across 8 CPU cores. PM2 automatically restarts crashed workers, performs rolling reloads during deployment, and exposes metrics via HTTP API.

PM2 Path

flowchart LR
  A[Profiling] --> B[PM2]
  B --> C[Docker]
  C --> D[Security]
  D --> E[Deployment]
  B --> F{You Are Here}
  style F fill:#f90,color:#fff

Installation and Basic Usage

# Install PM2 globally
npm install -g pm2

# Start an application
pm2 start app.js --name my-app

# List all running processes
pm2 list

# Show process details
pm2 show my-app

# Stop a process
pm2 stop my-app

# Delete a process
pm2 delete my-app

Cluster Mode

PM2 cluster mode starts one process per CPU core, distributing HTTP requests across all workers.

// Start with cluster mode
// pm2 start app.js -i max
// Or specify instance count
// pm2 start app.js -i 4
const http = require("node:http");
const cluster = require("node:cluster");
const server = http.createServer((req, res) => {
  res.end(`Worker ${process.pid} handled request\n`);
});
server.listen(3000);
console.log(`Worker ${process.pid} started`);

Ecosystem File

The ecosystem.config.js file defines all PM2 configuration in a reusable format.

// ecosystem.config.js
module.exports = {
  apps: [{
    name: "api-server",
    script: "./dist/server.js",
    instances: "max",
    exec_mode: "cluster",
    env: { NODE_ENV: "development" },
    env_production: { NODE_ENV: "production" },
    max_memory_restart: "500M",
    log_date_format: "YYYY-MM-DD HH:mm:ss Z",
    error_file: "./logs/error.log",
    out_file: "./logs/output.log",
    merge_logs: true,
    watch: false,
    max_restarts: 10,
    restart_delay: 1000,
  }],
};

Zero-Downtime Reload

Graceful reload restarts workers one by one without dropping requests.

# Reload with zero downtime
pm2 reload all

# Graceful shutdown (app must handle SIGINT)
pm2 start app.js --kill-timeout 3000

# Reload specific app
pm2 reload api-server

# Start with graceful shutdown

Monitoring and Metrics

PM2 provides built-in monitoring via CLI commands and a web dashboard.

# Real-time monitoring dashboard
pm2 monit

# Process list with resource usage
pm2 list

# Detailed process info
pm2 show api-server

# CPU and memory usage for all processes
pm2 prettylist

# PM2 Plus dashboard (cloud)
pm2 plus

Startup Scripts

Generate and configure PM2 to start on system boot.

# Generate startup script
pm2 startup

# Save current process list for startup
pm2 save

# The startup hook runs on system boot
# pm2 resurrect restores all saved processes

Common Mistakes

1. Not Setting max_memory_restart

Without memory limits, a leaking process continues growing until it crashes. Set max_memory_restart to auto-restart.

2. Using Default Log Settings

PM2 logs grow unbounded. Configure log rotation or use external logging.

3. Not Handling SIGINT for Graceful Shutdown

PM2 sends SIGINT for reload. The app must close connections and exit within kill_timeout.

4. Running in Fork Mode for HTTP Services

Single process cannot utilize multiple CPUs. Use cluster mode or combine with PM2 fork mode for non-HTTP workers.

5. Forgetting to Run pm2 save After Changes

Updated process lists are lost on reboot if pm2 save is not run after changes.

Practice Questions

1. What does the -i max flag do?

Starts as many instances as there are CPU cores, enabling cluster mode for load distribution.

2. How does PM2 achieve zero-downtime reload?

It restarts workers one at a time, waiting for each to signal readiness before restarting the next.

3. What is the ecosystem file?

A JavaScript configuration file (ecosystem.config.js) that defines all PM2 application settings.

4. What does pm2 startup do?

Generates a systemd/init script so PM2 starts automatically when the server boots.

5. Challenge: Configure PM2 for a 4-instance cluster with memory limits and log rotation.

module.exports = {
  apps: [{
    name: "api",
    script: "server.js",
    instances: 4,
    exec_mode: "cluster",
    max_memory_restart: "256M",
    log_date_format: "YYYY-MM-DD HH:mm",
    error_file: "./logs/err.log",
    out_file: "./logs/out.log",
  }],
};

FAQ

Is PM2 necessary in Docker containers?

Less necessary. Docker provides restart policies. But PM2 cluster mode still helps utilize multi-core containers.

How does PM2 handle uncaught exceptions?

PM2 catches uncaught exceptions and restarts the process. The new instance starts fresh.

Can PM2 monitor remote servers?

PM2 Plus provides a web dashboard. For basic monitoring, use pm2 monit on each server.

What is the difference between pm2 reload and pm2 restart?

Restart stops all processes at once (downtime). Reload restarts one by one (zero-downtime).

Does PM2 work with TypeScript?

Yes. PM2 can run ts-node directly or use compiled JavaScript output.

Mini Project: PM2 Deployment Script

Build a deployment script that performs zero-downtime updates.

const { execSync } = require("node:child_process");
function deploy() {
  console.log("1. Pulling latest code...");
  execSync("git pull origin main", { stdio: "inherit" });
  console.log("2. Installing dependencies...");
  execSync("npm ci --production", { stdio: "inherit" });
  console.log("3. Building...");
  execSync("npm run build", { stdio: "inherit" });
  console.log("4. Reloading application...");
  execSync("pm2 reload ecosystem.config.js", { stdio: "inherit" });
  console.log("5. Deployment complete");
}
deploy();

What's Next

Node.js Docker Node.js Security Node.js Deployment

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro