Tutorials

PM2 for Node.js - Complete Guide

February 18, 2026
14 min read read
M
Manas

PM2 is the most popular process manager for Node.js applications. It keeps your apps running, handles restarts, and provides powerful monitoring. This guide covers everything from basics to advanced usage.

What is PM2?

PM2 (Process Manager 2) is a production process manager for Node.js with:

  • Process management (start, stop, restart)
  • Auto-restart on crashes
  • Load balancing with cluster mode
  • Log management
  • Monitoring dashboard
  • Deployment system

Installation

Global Installation

npm install -g pm2

Verify Installation

pm2 --version

Basic Usage

Start an Application

# Start a script
pm2 start app.js

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

# Start npm script
pm2 start npm --name my-app -- start

Manage Processes

pm2 list                 # List all processes
pm2 stop my-app          # Stop a process
pm2 restart my-app       # Restart a process
pm2 delete my-app        # Remove from PM2
pm2 stop all             # Stop all processes
pm2 restart all          # Restart all processes

View Logs

pm2 logs                 # All logs
pm2 logs my-app          # Specific app logs
pm2 logs --lines 100     # Last 100 lines
pm2 flush                # Clear all logs

Ecosystem Configuration

For complex setups, use an ecosystem file.

Create ecosystem.config.js

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    instances: 2,
    autorestart: true,
    watch: false,
    max_memory_restart: '1G',
    env: {
      NODE_ENV: 'development'
    },
    env_production: {
      NODE_ENV: 'production'
    }
  }]
};

Start with Ecosystem

pm2 start ecosystem.config.js
pm2 start ecosystem.config.js --env production

Cluster Mode

Cluster mode runs multiple instances for better performance.

Enable Clustering

# Start with specific instances
pm2 start app.js -i 4

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

Ecosystem Cluster Config

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    instances: 'max',
    exec_mode: 'cluster',
    instance_var: 'INSTANCE_ID'
  }]
};

Scale Instances

pm2 scale my-app 4       # Scale to 4 instances
pm2 scale my-app +2      # Add 2 instances
pm2 scale my-app -1      # Remove 1 instance

Auto-Restart Configuration

On System Reboot

pm2 startup              # Generate startup script
pm2 save                 # Save current process list

On File Changes (Development)

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    watch: true,
    ignore_watch: ['node_modules', 'logs'],
    watch_options: {
      followSymlinks: false
    }
  }]
};

On Memory Limit

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    max_memory_restart: '500M'
  }]
};

Monitoring

Built-in Monitor

pm2 monit

Shows real-time:

  • CPU usage
  • Memory usage
  • Loop delay
  • Request count

Process Information

pm2 show my-app          # Detailed info
pm2 describe my-app      # Same as show

PM2 Plus (Web Dashboard)

pm2 plus                 # Connect to PM2 Plus

Provides:

  • Web-based dashboard
  • Historical metrics
  • Alerting
  • Remote management

Log Management

Log Configuration

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    output: './logs/out.log',
    error: './logs/error.log',
    log_date_format: 'YYYY-MM-DD HH:mm:ss',
    merge_logs: true
  }]
};

Log Rotation

Install pm2-logrotate:

pm2 install pm2-logrotate

Configure:

pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true

Environment Variables

In Ecosystem File

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    env: {
      NODE_ENV: 'development',
      PORT: 3000
    },
    env_production: {
      NODE_ENV: 'production',
      PORT: 8080
    },
    env_staging: {
      NODE_ENV: 'staging',
      PORT: 3001
    }
  }]
};

Switch Environments

pm2 start ecosystem.config.js --env production
pm2 restart my-app --env staging

Deployment

Deployment Configuration

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js'
  }],
  deploy: {
    production: {
      user: 'deploy',
      host: 'your_server_ip',
      ref: 'origin/main',
      repo: 'git@github.com:user/repo.git',
      path: '/var/www/my-app',
      'pre-deploy-local': '',
      'post-deploy': 'npm install && pm2 reload ecosystem.config.js --env production',
      'pre-setup': ''
    }
  }
};

Deploy Commands

# Initial setup
pm2 deploy production setup

# Deploy
pm2 deploy production

# Rollback
pm2 deploy production revert 1

Graceful Shutdown

Handle shutdown signals properly:

In Your App

process.on('SIGINT', async () => {
  console.log('Shutting down gracefully...');
  
  // Close database connections
  await db.close();
  
  // Close server
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
  
  // Force exit after timeout
  setTimeout(() => {
    process.exit(1);
  }, 10000);
});

PM2 Configuration

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    kill_timeout: 5000,
    wait_ready: true,
    listen_timeout: 10000
  }]
};

Common Patterns

Discord Bot

module.exports = {
  apps: [{
    name: 'discord-bot',
    script: 'bot.js',
    instances: 1,
    autorestart: true,
    max_memory_restart: '500M',
    env: {
      NODE_ENV: 'production',
      DISCORD_TOKEN: 'your_token'
    }
  }]
};

API Server with Clustering

module.exports = {
  apps: [{
    name: 'api-server',
    script: 'server.js',
    instances: 'max',
    exec_mode: 'cluster',
    max_memory_restart: '1G',
    env_production: {
      NODE_ENV: 'production',
      PORT: 3000
    }
  }]
};

Multiple Apps

module.exports = {
  apps: [
    {
      name: 'api',
      script: 'api/server.js',
      instances: 4,
      exec_mode: 'cluster'
    },
    {
      name: 'worker',
      script: 'worker/index.js',
      instances: 2
    },
    {
      name: 'scheduler',
      script: 'scheduler/cron.js',
      instances: 1
    }
  ]
};

Troubleshooting

Process Keeps Restarting

Check logs for errors:

pm2 logs my-app --err --lines 50

High Memory Usage

  • Check for memory leaks
  • Set max_memory_restart
  • Review your code for issues

Cluster Mode Issues

Not all apps work in cluster mode. Ensure:

  • No shared state between instances
  • Use Redis for sessions
  • Stateless design

Useful Commands Reference

# Process management
pm2 start app.js
pm2 stop all
pm2 restart all
pm2 delete all

# Monitoring
pm2 list
pm2 monit
pm2 show app-name

# Logs
pm2 logs
pm2 flush

# System
pm2 startup
pm2 save
pm2 unstartup

# Updates
pm2 update

Conclusion

PM2 is essential for running Node.js in production. It handles crashes, provides monitoring, and enables zero-downtime deployments. Start with basic usage and gradually adopt advanced features as needed.

HeavenCloud hosting works perfectly with PM2, providing the reliable infrastructure your Node.js applications need.

Start building your community

Deploy high-performance Discord bots, Lavalink nodes, and VPS servers with instant setup on HeavenCloud.