Back to Engineering Blog
DevOps5 min read

Zero-Downtime Releases with PM2 Cluster Mode

Why we invoke the Next.js binary directly instead of through npm, and how that one detail is what makes a rolling reload actually roll.

Glacro · Published August 2, 2026

Two Next.js instances run behind nginx under PM2 in cluster mode. A release restarts them one at a time, so there is always an instance answering. The detail that makes it work is not obvious.

Do not start it with npm

javascript
{
  // Not "npm" with args "start".
  script: "node_modules/next/dist/bin/next",
  args: "start",
  exec_mode: "cluster",
  instances: 2,
}

Running npm start makes npm the supervised process and next start a child of it. PM2 can only share a listening socket across processes it forked itself, so with npm in between, cluster mode stops load-balancing and a rolling reload stops being rolling. Invoking the Next.js binary directly puts the actual server under PM2's control.

The reload

pm2 reload restarts instances sequentially and waits for each to come up before moving to the next. With two instances, one is always serving. A restart, by contrast, stops everything and then starts it — the difference is a few seconds of refused connections on every deploy.

Key Takeaway
The working directory in the process config must match the directory the deploy script writes to. Ours drifted once during a rename and the site served a build that had been deleted from disk.

Related Articles

Product Updates

What Glacro Actually Runs, and What It Doesn't

August 26, 2026 · 6 min read
Tutorials

Deploying a Next.js 14 Static Export

August 20, 2026 · 7 min read