Skip to main content

What is PM2?

The Problem with node app.js

When you SSH into a server and run your app directly:

node app.js

Three things happen that make this unsuitable for production:

  1. The process dies when you close the SSH session — it's tied to your terminal
  2. A crash kills the app — nothing restarts it automatically
  3. Server reboots kill the app — it doesn't come back after a restart

PM2 solves all three.

How PM2 Works

PM2 runs as a daemon — a background service that outlives your SSH session. It:

  • Starts your Node.js app as a managed process
  • Monitors it and restarts it if it crashes
  • Can generate a startup script so it relaunches after a server reboot
  • Collects stdout/stderr into log files you can read at any time

Installing PM2

npm install -g pm2

Verify:

pm2 --version

Core Commands

Starting an App

pm2 start app.js # start with default name ("app")
pm2 start app.js --name my-api # give it a meaningful name
pm2 start app.js --watch # restart on file changes (dev use)
pm2 start npm -- start # run `npm start` via PM2

Viewing Status

pm2 status # list all managed processes with CPU/memory
pm2 list # alias for status
pm2 show my-api # detailed info about a specific process

Example output of pm2 status:

┌─────┬──────────┬─────────────┬─────────┬─────────┬──────────┬────────┐
│ id │ name │ status │ cpu │ memory │ uptime │ restarts│
├─────┼──────────┼─────────────┼─────────┼─────────┼──────────┼────────┤
│ 0 │ my-api │ online │ 0% │ 45.3mb │ 2h │ 0 │
└─────┴──────────┴─────────────┴─────────┴─────────┴──────────┴────────┘

Logs

pm2 logs # stream logs from all processes
pm2 logs my-api # logs for a specific process
pm2 logs --lines 200 # show last 200 lines
pm2 flush # clear all log files

Restarting and Stopping

pm2 restart my-api # restart (brief downtime)
pm2 reload my-api # zero-downtime reload (graceful restart)
pm2 stop my-api # stop without removing from PM2's list
pm2 delete my-api # stop and remove from PM2's list

Cluster Mode

Node.js runs on a single thread. On a server with 8 CPU cores, you're only using one. PM2's cluster mode forks your app across all available cores, multiplying throughput:

pm2 start app.js --name my-api -i max # -i max = one instance per CPU core
pm2 start app.js -i 4 # exactly 4 instances

PM2 automatically load-balances incoming connections across all instances. This is effectively free horizontal scaling without any code changes.

Surviving Server Reboots

By default, PM2's process list is lost on reboot. Fix this with:

pm2 startup # generates and prints a command to run
# → copy and run the printed command (it'll look like: sudo env PATH=... pm2 startup systemd -u ubuntu --hp /home/ubuntu)

pm2 save # saves the current process list to disk

After this, PM2 will restart all your apps automatically whenever the server boots.

Real-Time Monitoring

pm2 monit

Opens a terminal dashboard showing CPU usage, memory, logs, and event loop delay for all processes in real time.