PM2 Cluster Mode: Setup, Configuration, and Production Deployment

Topic: pm2-cluster-mode-port-already-in-useUpdated 7/15/2026

Quick Answer

  • What it does: PM2 Cluster Mode runs multiple instances of your Node.js application across all available CPU cores, providing load balancing and high availability for network applications (HTTP/HTTPS/TCP/UDP).
  • Minimal command: pm2 start app.js -i max — this starts your app in cluster mode, automatically creating one worker per CPU core.
  • Key requirement: Your application must be stateless (no in-memory session data, no local file writes from multiple workers) for cluster mode to work correctly.
  • Zero-downtime reload: Use pm2 reload <app_name> instead of pm2 restart to restart workers one by one without dropping connections.
  • Version boundary: Works with Node.js 0.12+ and PM2 1.0+. The -i flag is required to enable cluster mode; without it, PM2 defaults to fork mode.

What Problem It Solves

Node.js runs on a single thread by default, meaning it cannot utilize multiple CPU cores on a single machine. For production network applications (REST APIs, microservices, WebSocket servers), this limits throughput and creates a single point of failure.

PM2 Cluster Mode solves this by using Node.js's built-in cluster module to spawn multiple worker processes that share the same server port. The master process distributes incoming connections across workers using a round-robin algorithm, providing:

  • CPU utilization: All cores are used, increasing request handling capacity
  • High availability: If one worker crashes, the master spawns a replacement
  • Zero-downtime deployments: Workers restart sequentially during pm2 reload

Installation and Quick Start

Install PM2 globally:

BASH
npm install -g pm2

Start your application in cluster mode:

BASH
pm2 start app.js -i max

This single command:

  • Enables cluster mode (the -i flag is required)
  • Creates one worker per CPU core (max)
  • Names the process after the script filename
  • Daemonizes the process (runs in background)

To verify it's working:

BASH
pm2 list
pm2 monit

Parameters and Environment Variables

The -i (instances) Parameter

The -i flag is required to enable cluster mode. Without it, PM2 runs in fork mode (single process).

ValueBehavior
maxCreates one worker per CPU core
0Same as max
-1Creates (CPU cores - 1) workers
3Creates exactly 3 workers
2Creates exactly 2 workers

Example with a specific number:

BASH
pm2 start app.js -i 4 --name my-api

Configuration File (ecosystem.config.js)

For production, use a configuration file instead of CLI flags:

JAVASCRIPT
module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    env_development: {
      NODE_ENV: 'development',
      PORT: 3001
    }
  }]
};

Start with the config file:

BASH
pm2 start ecosystem.config.js

Switch environments:

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

Root Cause Analysis: Why Cluster Mode Fails

Statelessness Requirement

PM2 Cluster Mode distributes requests across workers using round-robin. If your application stores session data in memory, a user's request may hit a different worker on the next request, losing the session.

Symptoms: Users are randomly logged out, shopping carts disappear, form data is lost.

Fix: Use an external session store (Redis, Memcached, database) or make the application stateless.

File System Conflicts

Multiple workers writing to the same file (logs, SQLite databases, temporary files) causes data corruption.

Symptoms: Corrupted log files, SQLITE_BUSY errors, missing data.

Fix:

  • Use a logging library that supports concurrent writes (e.g., Winston with file rotation)
  • Replace SQLite with PostgreSQL or MySQL
  • Use Redis for caching instead of local files

Port Binding Issues

Cluster mode workers share the parent process's port automatically. However, if your application explicitly binds to a port in the worker code, you may see EADDRINUSE errors.

Fix: Only call server.listen() once in the master process, or let PM2 handle port sharing automatically.

Common Errors and Fixes

ErrorCauseSolution
Error: listen EADDRINUSE: address already in use :::3000Port already occupiedlsof -i :3000 to find the process, then kill it or change the port
Error: Cannot find module 'app.js'Wrong script pathUse absolute path or run PM2 from the project root directory
Error: Process exited with code 1Application startup failureCheck pm2 logs for detailed error (missing dependencies, syntax errors, missing env vars)
pm2: command not foundPM2 not installed or not in PATHRun npm install -g pm2 or use npx pm2

Production Notes and Security Checks

Essential Production Setup

BASH
# Save the process list for automatic recovery
pm2 save

# Generate startup script (systemd, init.d, etc.)
pm2 startup

# Monitor logs
pm2 logs

# Monitor metrics
pm2 monit

Security and Resource Limits

  1. File permissions: PM2 runs as the current user. Ensure log directories, PID files, and application directories have correct permissions.

  2. File descriptor limits: Cluster mode multiplies open file handles. Increase the system limit:

    BASH
    ulimit -n 65536
    
  3. Firewall: PM2 does not provide network isolation. Always put a reverse proxy (Nginx, HAProxy) in front of PM2-managed applications.

  4. Graceful shutdown: Your application should listen for SIGINT to clean up connections:

    JAVASCRIPT
    process.on('SIGINT', () => {
      server.close(() => process.exit(0));
    });
    

Zero-Downtime Deployment

BASH
# Instead of restart (kills all workers at once)
pm2 reload my-app

# Force reload if graceful shutdown fails
pm2 reload my-app --kill-timeout 3000

The reload command restarts workers one by one, ensuring at least one worker is always serving requests.

Comparison With Alternatives

FeaturePM2 Cluster ModeNginx + PM2 ForkDocker Swarm / Kubernetes
Load balancingRound-robin (built-in)Multiple algorithms (least connections, IP hash, etc.)Service mesh / ingress
Zero-downtimepm2 reloadRequires Nginx reloadRolling updates
Process managementNode.js-focusedRequires separate Nginx configFull container orchestration
Learning curveLowMediumHigh
Resource overheadMinimalModerate (Nginx process)High (control plane)
Stateful app supportNo (must be stateless)Yes (sticky sessions via IP hash)Yes (with persistent volumes)

When to use PM2 Cluster Mode: Small to medium Node.js applications on a single server, where simplicity and low overhead matter more than advanced routing features.

When to use alternatives: Multi-server deployments, applications requiring sticky sessions, or when you need advanced load-balancing algorithms.

FAQ

Q: What is the difference between PM2 Cluster Mode and PM2 Fork Mode?

A: Fork Mode is the default. Each instance runs in a separate process with its own port, suitable for non-network applications (cron jobs, scripts). Cluster Mode uses Node.js's cluster module so workers share the same port, provides built-in load balancing, and is designed for network applications. Cluster Mode requires stateless applications; Fork Mode has no such restriction.

Q: How do I achieve zero-downtime deployment with PM2 Cluster Mode?

A: Use pm2 reload <app_name>. PM2 restarts workers one by one, ensuring at least one worker is always serving. Your application should listen for SIGINT to perform graceful shutdown (close database connections, finish current requests). If the app doesn't close within the timeout, PM2 force-kills it.

Q: How do I manage environment variables in cluster mode?

A: Set them in the ecosystem.config.js file under the env field. All workers inherit the same environment variables. Example:

JAVASCRIPT
{
  apps: [{
    script: 'app.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: { NODE_ENV: 'production', PORT: 3000 }
  }]
}

You can also use pm2 start app.js --env production to switch environments.

Related Guides