Tutorial 📅 November 10, 2025 📖 8 min read

PM2 Tutorial: Deploy Node.js Apps Like a Pro (2025)

Complete PM2 tutorial for Node.js deployment. Learn PM2 commands, auto-restart, load balancing, monitoring, and production best practices. Step-by-step guide with examples.

You've built your Node.js application, and it runs perfectly on your local machine. But when you deploy it to production, you need more than just node app.js. What happens when your app crashes? What if the server reboots? How do you handle multiple CPU cores?

This is where PM2 comes in. PM2 is the industry-standard process manager for Node.js applications, trusted by developers worldwide to keep production apps running 24/7.

In this comprehensive tutorial, you'll learn everything you need to know about PM2 - from basic deployment to advanced clustering and monitoring.

What You'll Learn:
✅ Installing and configuring PM2
✅ Essential PM2 commands for daily use
✅ Setting up auto-restart on crashes and reboots
✅ Load balancing with cluster mode
✅ Real-time monitoring and log management
✅ Production deployment best practices

What is PM2 and Why Should You Use It?

PM2 (Process Manager 2) is a production-grade process manager for Node.js applications. Think of it as a supervisor that watches over your app and ensures it stays running no matter what.

Key Benefits of PM2:

Real-World Impact: Companies using PM2 report 99.9% uptime, automatic recovery from crashes, and 4x performance improvements with cluster mode on multi-core servers.

Installing PM2 on Your VPS

Before installing PM2, make sure you have Node.js and npm installed on your server.

Check Node.js Installation:

node --version
npm --version

If you don't have Node.js installed, install it first:

# Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# Verify installation
node --version  # Should show v20.x.x

Install PM2 Globally:

npm install -g pm2

# Verify installation
pm2 --version
Permission Issues? If you get EACCES errors, use: sudo npm install -g pm2
Or better yet, configure npm to install global packages without sudo (search "npm global without sudo")

PM2 Basics: Starting Your First App

Let's start with the most basic PM2 commands. We'll use a simple Express.js app as an example.

Simple Node.js App (app.js):

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello from PM2!');
});

app.listen(port, () => {
  console.log(`App running on port ${port}`);
});

Start Your App with PM2:

# Basic start
pm2 start app.js

# Start with a custom name
pm2 start app.js --name "my-api"

# Start with environment variables
pm2 start app.js --name "my-api" --env production

Check Running Processes:

pm2 list  # or pm2 ls

You'll see a beautiful table showing all your running apps with their status, CPU, and memory usage.

Essential PM2 Commands Every Developer Should Know

Here's your PM2 command cheat sheet for daily operations:

Process Management:

# Start an app
pm2 start app.js

# Start with specific name
pm2 start app.js --name "api-server"

# Stop an app
pm2 stop app-name  # or app-id (0, 1, 2...)

# Restart an app
pm2 restart app-name

# Reload with zero downtime
pm2 reload app-name

# Delete from PM2 list
pm2 delete app-name

# Stop all apps
pm2 stop all

# Restart all apps
pm2 restart all

# Delete all apps
pm2 delete all

Monitoring & Logs:

# View real-time dashboard
pm2 monit

# View logs (all apps)
pm2 logs

# View logs for specific app
pm2 logs app-name

# Clear all logs
pm2 flush

# View app details
pm2 show app-name

# View process list
pm2 list  # or pm2 ls or pm2 status

Information & Metadata:

# Detailed app information
pm2 describe app-name

# Show environment variables
pm2 env 0  # replace 0 with app id

# PM2 version
pm2 --version
Pro Tip: Use pm2 monit for a beautiful real-time dashboard. It's like top but specifically for your Node.js apps!

Cluster Mode: Maximizing Performance

One of PM2's killer features is cluster mode. By default, Node.js runs on a single thread. On a server with 8 CPU cores, you're only using 12.5% of your computing power!

PM2's cluster mode automatically load-balances incoming requests across multiple Node.js processes, utilizing all CPU cores.

Start in Cluster Mode:

# Use all available CPU cores
pm2 start app.js -i max

# Specify number of instances
pm2 start app.js -i 4

# Or use -1 for (CPU cores - 1)
pm2 start app.js -i -1

When to Use Cluster Mode:

Scale Up/Down Dynamically:

# Scale to 8 instances
pm2 scale app-name 8

# Add 2 more instances
pm2 scale app-name +2

# Remove 1 instance
pm2 scale app-name -1
Performance Boost: Users report 3-5x throughput improvements when switching from single-instance to cluster mode on multi-core servers!

Auto-Restart on Server Reboot (Startup Scripts)

Your server rebooted, and now your app is down. This is unacceptable in production. PM2's startup script feature solves this.

Setup Auto-Startup (One-Time Setup):

# 1. Generate startup script
pm2 startup

# PM2 will output a command like:
# sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u youruser --hp /home/youruser

# 2. Run the generated command (copy-paste the exact command PM2 shows)
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u youruser --hp /home/youruser

# 3. Save current process list
pm2 save

How It Works:

  1. pm2 startup detects your init system (systemd, upstart, etc.)
  2. It generates a startup script for your OS
  3. You run the generated command with sudo to install it
  4. pm2 save saves your current PM2 process list
  5. On reboot, PM2 automatically starts all saved processes

Update Saved Process List:

# After adding/removing apps, update the saved list
pm2 save

# To unsave and disable auto-startup
pm2 unstartup
pm2 kill
Important: Always run pm2 save after changing your process list. Otherwise, your changes won't persist after reboot!

Environment Variables & Ecosystem Files

Managing complex apps with multiple environment variables using CLI flags gets messy fast. PM2 ecosystem files solve this elegantly.

Generate Ecosystem File:

pm2 ecosystem

This creates ecosystem.config.js. Here's a production-ready example:

ecosystem.config.js:

module.exports = {
  apps: [
    {
      name: 'api-server',
      script: './app.js',
      instances: 'max',  // or number
      exec_mode: 'cluster',  // or 'fork'
      watch: false,  // Enable in dev: true
      max_memory_restart: '1G',  // Auto-restart if exceeds 1GB
      env: {
        NODE_ENV: 'development',
        PORT: 3000,
        DATABASE_URL: 'mongodb://localhost/dev'
      },
      env_production: {
        NODE_ENV: 'production',
        PORT: 8080,
        DATABASE_URL: 'mongodb://localhost/prod'
      },
      error_file: './logs/err.log',
      out_file: './logs/out.log',
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
      merge_logs: true,
      autorestart: true,
      max_restarts: 10,
      min_uptime: '10s'
    },
    {
      name: 'worker',
      script: './worker.js',
      instances: 2,
      exec_mode: 'cluster',
      env: {
        WORKER_QUEUE: 'redis://localhost:6379'
      }
    }
  ]
};

Using Ecosystem Files:

# Start all apps in ecosystem file
pm2 start ecosystem.config.js

# Start with production environment
pm2 start ecosystem.config.js --env production

# Start specific app from ecosystem
pm2 start ecosystem.config.js --only api-server

# Reload all apps from ecosystem
pm2 reload ecosystem.config.js
Best Practice: Always use ecosystem files for production deployments. They're version-controlled, repeatable, and much cleaner than command-line flags.

Log Management with PM2

PM2 automatically captures stdout and stderr from your apps. But logs can grow massive over time, so proper management is crucial.

View Logs:

# All apps
pm2 logs

# Specific app
pm2 logs api-server

# Last 100 lines
pm2 logs --lines 100

# JSON format
pm2 logs --json

# Only errors
pm2 logs --err

Log File Locations:

~/.pm2/logs/app-name-out.log  # stdout
~/.pm2/logs/app-name-error.log  # stderr

Clear All Logs:

pm2 flush

Log Rotation (Prevent Disk Space Issues):

# Install PM2 log rotation module
pm2 install pm2-logrotate

# Configure rotation (optional)
pm2 set pm2-logrotate:max_size 10M  # Rotate when log hits 10MB
pm2 set pm2-logrotate:retain 30  # Keep 30 rotated logs
pm2 set pm2-logrotate:compress true  # Gzip old logs
Production Warning: Without log rotation, your logs WILL fill up your disk eventually. Always install pm2-logrotate in production!

Advanced PM2 Features

1. Max Memory Restart

Automatically restart your app if it exceeds a memory threshold (prevents memory leaks from killing your server):

pm2 start app.js --max-memory-restart 1G

2. Watch & Restart on File Changes (Development)

# Watch all files
pm2 start app.js --watch

# Ignore specific folders
pm2 start app.js --watch --ignore-watch="node_modules logs"

3. Graceful Shutdown

Handle cleanup before restart (close DB connections, finish requests):

// In your app.js
process.on('SIGINT', async () => {
  console.log('Gracefully shutting down...');
  await db.close();
  await cache.disconnect();
  process.exit(0);
});
# Set shutdown timeout (default 1600ms)
pm2 start app.js --kill-timeout 5000

4. Cron Restart

Restart your app on a schedule (useful for apps with memory leaks you can't fix immediately):

# Restart every day at 3 AM
pm2 start app.js --cron-restart="0 3 * * *"

5. Disable Auto-Restart

pm2 start app.js --no-autorestart

Tired of Terminal Commands? Manage PM2 Visually

VPS Commander provides a beautiful web interface to manage PM2 processes, view logs, restart apps, and monitor performance - all without touching the terminal. Perfect for developers who want the power of PM2 with the convenience of a GUI.

Try VPS Commander Free

Production Deployment Best Practices

1. Always Use Ecosystem Files

# Create ecosystem.config.js in your project root
pm2 init

# Edit it, then deploy
pm2 start ecosystem.config.js --env production
pm2 save

2. Enable Cluster Mode for Web Servers

instances: 'max',
exec_mode: 'cluster'

3. Set Memory Limits

max_memory_restart: '1G'

4. Configure Log Rotation

pm2 install pm2-logrotate

5. Set Up Startup Script

pm2 startup
# Run the generated command
pm2 save

6. Use Environment Variables

Never hardcode secrets. Use env files or ecosystem config:

env_production: {
  DATABASE_URL: process.env.DATABASE_URL,
  API_KEY: process.env.API_KEY
}

7. Implement Health Checks

Add a health endpoint to your app:

app.get('/health', (req, res) => {
  res.status(200).json({ status: 'ok', uptime: process.uptime() });
});

8. Monitor with PM2 Plus (Optional)

PM2 Plus provides advanced monitoring, alerting, and dashboards:

pm2 link <secret-key> <public-key>

Common PM2 Errors & Solutions

Error: "EADDRINUSE: Address already in use"

Cause: Another process is using the port.

# Find and kill the process
sudo lsof -i :3000
kill -9 <PID>

# Or use a different port
PORT=3001 pm2 start app.js

Error: "Script not found"

Cause: PM2 can't find your app file.

# Use absolute path
pm2 start /home/user/app/app.js

# Or cd to the directory first
cd /home/user/app
pm2 start app.js

App Keeps Restarting (Crash Loop)

Cause: Your app is crashing immediately after start.

# Check error logs
pm2 logs app-name --err

# Check why it's crashing
pm2 describe app-name

PM2 Processes Not Starting After Reboot

Cause: Startup script not configured or pm2 save not run.

pm2 startup
# Run the generated command
pm2 save

PM2 vs Other Process Managers

Feature PM2 Forever Systemd
Cluster Mode ✅ Built-in ❌ No ⚠️ Manual
Zero-Downtime Reload ✅ Yes ❌ No ❌ No
Monitoring Dashboard ✅ pm2 monit ❌ No ⚠️ journalctl
Log Management ✅ Advanced ✅ Basic ✅ journald
Easy to Use ✅ Very ✅ Yes ⚠️ Complex
Node.js Specific ✅ Optimized ✅ Yes ❌ Generic

Verdict: PM2 is the clear winner for Node.js applications. It's specifically designed for Node.js, offers the most features, and is incredibly easy to use.

Quick Reference: PM2 Command Cheat Sheet

# START
pm2 start app.js
pm2 start app.js --name "api"
pm2 start app.js -i max  # cluster mode

# RESTART/RELOAD/STOP
pm2 restart app-name
pm2 reload app-name  # zero-downtime
pm2 stop app-name
pm2 delete app-name

# MONITORING
pm2 list
pm2 monit
pm2 logs
pm2 logs app-name
pm2 describe app-name

# CLUSTER
pm2 start app.js -i max
pm2 scale app-name 4

# STARTUP
pm2 startup
pm2 save
pm2 resurrect

# ECOSYSTEM
pm2 init
pm2 start ecosystem.config.js
pm2 start ecosystem.config.js --env production

# LOGS
pm2 logs
pm2 flush
pm2 install pm2-logrotate

# UPDATES
pm2 update
npm install -g pm2@latest

Conclusion: Master PM2 for Bulletproof Node.js Deployments

PM2 transforms Node.js deployment from fragile and manual to robust and automated. With PM2, you get:

Start with the basics (pm2 start app.js -i max), set up auto-restart (pm2 startup && pm2 save), and gradually adopt advanced features as your app grows.

Next Steps:
1. Install PM2 on your VPS
2. Deploy your first app with cluster mode
3. Set up startup script for auto-restart
4. Install log rotation
5. Create an ecosystem file for reproducible deployments

Your Node.js apps will thank you!

Related Articles