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.jsrun directly has zero built-in resilience: if the process exits for any reason (an uncaught exception, an unhandled rejection crashing the process, a genuineprocess.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.jsgenuinely 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 logsaggregating output across restarts, rather than a lost terminal scrollback); and process monitoring (real CPU/memory/uptime/restart-count visible viapm2 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.