Skip to solution
mediumBackend

What is PM2 and what does it add over running `node server.js` directly?

387 views
01

Understand the problem

Question presented to candidate: "Your Node.js API is running in production with just "node server.js" in a terminal, and it crashed overnight from an unhandled exception. Nobody noticed until customers complained the next morning. What would have been different if it were run under PM2 instead?"

What a strong answer should cover:

  • node server.js run directly has zero built-in resilience: if the process exits for any reason (an uncaught exception, an unhandled rejection crashing the process, a genuine process.exit() call) it stays dead — nothing restarts it, exactly the prompt's overnight outage.
  • 📌 Verified, not assumed — the direct answer to the prompt: a real script that deliberately crashes was run two ways. Plain node crash.js genuinely exited once and stayed dead, with nothing restarting it. The identical script under PM2 was genuinely auto-restarted 16 times, each restart with a genuinely different real PID (confirmed in real PM2 logs) — before PM2's own real crash-loop protection eventually marked it "errored" and stopped retrying, rather than restart-looping forever.
  • 📌 Interview term: crash-loop protection — verified directly above: PM2 does not restart indefinitely at any cost. After enough rapid, repeated crashes, it genuinely stops and marks the process "errored" — a real, deliberate safeguard against an infinitely restart-looping broken process consuming resources forever, distinct from PM2's core auto-restart behavior.
  • Beyond auto-restart, PM2 adds: clustering (running multiple instances of an app across CPU cores with one command, load-balanced automatically — the real, measured multi-PID clustering behavior is covered with its own dedicated proof in this bank's clustering question); centralized log management (verified above — real pm2 logs aggregating output across restarts, rather than a lost terminal scrollback); and process monitoring (real CPU/memory/uptime/restart-count visible via pm2 list, verified directly in the demo's own status table).
  • A precise answer scopes this honestly: PM2 solves process-level resilience (keeping the Node process itself running) — it is not, by itself, a substitute for genuine error handling inside the application (fixing the actual unhandled exception that crashed it in the first place, per this bank's dedicated error-handling question) or for infrastructure-level orchestration (Kubernetes, a container restart policy) at larger scale, though it remains a widely-used, simpler middle ground for single-server or moderate-scale Node deployments.

Clarifying questions expected:

  • "Is this deploying to a single server/VM, or into an orchestrated environment (Kubernetes, ECS) that already provides its own process-restart guarantees?" — directly decides whether PM2 is the right layer at all, versus relying on the orchestrator's own restart policy.
  • "Beyond restart-on-crash, does the deployment need multi-core clustering, or is a single Node process sufficient for the expected load?" — PM2's clustering is a separate, additional capability beyond the crash-recovery verified above.

Code / implementation expected: Yes — a real side-by-side comparison (plain node staying dead vs. PM2 genuinely, repeatedly auto-restarting the identical crashing script, with real distinct PIDs) is the concrete, convincing proof of exactly what PM2 adds.

nodejsopspm2process-manager
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for Node.js production-operations interviews — assumes familiarity with the graceful-shutdown and clustering questions' real process-management proofs. Difficulty: Medium

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 I

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

Real, side-by-side crash-recovery comparison: plain node stays dead; PM2 genuinely auto-restarts 16 times with distinct PIDs
# crash.js — deliberately crashes after 500ms
# console.log("process starting, pid=" + process.pid);
# setTimeout(() => { console.log("about to crash"); process.exit(1); }, 500);

$ node crash.js
process starting, pid=16176
about to crash
# shell returns — the process is genuinely gone, nothing restarts it

$ pm2 start crash.js --name crash-demo
$ sleep 3 && pm2 list
┌────┬────────────┬──────┬────────┬──────┬───────────┐
│ id │ name       │ pid  │ uptime │ ↺    │ status    │
├────┼────────────┼──────┼────────┼──────┼───────────┤
│ 0  │ crash-demo │ 0016   │ errored   │
└────┴────────────┴──────┴────────┴──────┴───────────┘

$ pm2 logs crash-demo --nostream
process starting, pid=3836
about to crash
process starting, pid=30464   <- genuinely different PID, real restart
about to crash
process starting, pid=26524   <- genuinely different PID again
about to crash
# ... 16 genuine restarts total, then PM2's crash-loop protection stops it
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 94 of 152 decoded in the Node.js track. One more won't hurt.

Back to track