Skip to solution
easyPhone Screen

How do you run Node.js processes as a background service?

691 views
01

Understand the problem

Question presented to candidate: "You start a Node app with 'node server.js' in a terminal, close the terminal, and the app stops. What is actually happening, and what changes to make it run as a real background service?"

What a strong answer should cover:

  • Running node server.js directly in a terminal ties the process's lifetime to that shell session by default — closing the terminal (or the SSH session) sends a signal that terminates the child process along with it, which is why the app "stops" in the prompt's scenario.
  • 📌 The underlying mechanism, demonstrable directly: a child process spawned with { detached: true } and then .unref()'d genuinely survives its parent process exiting — this is the real OS-level capability every "run in the background" tool ultimately relies on, not magic.
  • In practice, hand-rolling detached/unref'd process spawning is rarely the right production answer — the standard tools exist specifically to add what raw detaching alone does not provide: automatic restart on crash, log management, and startup-on-boot integration.
  • pm2 is the most common Node-specific process manager: it restarts a crashed process automatically, manages logs, and supports a cluster mode across CPU cores — a userland tool, not an OS-level mechanism.
  • systemd (on modern Linux) is the OS-level init system's own service-management mechanism — a unit file describes how to start the process, and systemd itself handles restart policy, boot-time startup, and log capture via journald, with no Node-specific tooling required at all.
  • A precise answer distinguishes these by layer: nohup/detached-and-unref'd spawning is the raw OS-level survival mechanism; pm2 is a userland process manager built on top of that idea with restart/monitoring logic added; systemd is the OS's own init-system-level equivalent, generally preferred in production specifically because it is already the thing supervising every other system service, rather than adding another separate supervisor layer.

Clarifying questions expected:

  • "Is this a bare VM/Linux host, a containerized deployment, or a managed platform (a PaaS)?" — the right tool differs a lot: a container orchestrator (Kubernetes, ECS) typically already provides restart/supervision, making an in-container process manager partially redundant.
  • "Does the team already standardize on one process-management approach elsewhere?" — consistency with existing infrastructure often matters more than the specific tool's feature list.

Code / implementation expected: Optional — actually demonstrating a detached, unref'd child surviving its parent's exit is a strong, concrete way to show the underlying mechanism rather than just naming tool brand names.

pm2deploymentdevops
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/DevOps phone screens — assumes very basic child_process/Unix process familiarity. Difficulty: Easy

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:. The detached-process survival below

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

A real detached, unref'd child process outliving its parent, confirmed by a log file written after the parent exited
// bg-worker.cjs — the actual background work
const fs = require("fs");
let n = 0;
setInterval(() => {
  n++;
  fs.appendFileSync("bg-worker.log", `tick ${n} at ${Date.now()}\n`);
  if (n >= 3) process.exit(0);
}, 300);

// bg-spawner.cjs — the parent, which exits immediately
const { spawn } = require("child_process");
const child = spawn(process.execPath, ["bg-worker.cjs"], {
  detached: true,
  stdio: "ignore",
});
child.unref();
console.log("parent exiting immediately, child pid was", child.pid);
// process exits right here — the child keeps running independently

// $ node bg-spawner.cjs
// parent exiting immediately, child pid was 8768
// (parent has fully exited)
// $ cat bg-worker.log
// tick 1 at ...
// tick 2 at ...
// tick 3 at ...
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 13 of 152 decoded in the Node.js track. One more won't hurt.

Back to track