Skip to solution
mediumBackend

How do you design liveness and readiness health-check endpoints?

840 views
01

Understand the problem

Question presented to candidate: "Your service's database connection drops temporarily. If your ONE health-check endpoint returns an error whenever the database is unreachable, and your orchestrator (Kubernetes) is configured to restart the container on health-check failure, what happens — and is that genuinely the right response to a temporary database blip?"

What a strong answer should cover:

  • A single, combined health check that fails whenever ANY dependency (the database) is down causes exactly the prompt's real problem: the orchestrator, seeing a failing health check, restarts the container — but restarting the Node process does absolutely nothing to fix a database outage, which is the actual root cause. The restart is genuinely useless against this specific failure, and can make things worse (churning through restarts while the real underlying dependency is still down).
  • 📌 Interview term: liveness vs. readiness — a real, critical distinctionliveness answers "is the process itself alive and able to respond at all" (should trigger a restart if it fails); readiness answers "is the process currently able to serve real traffic correctly" (should trigger removal from load-balancer rotation, NOT a restart, if it fails).
  • 📌 Verified, not assumed — the exact answer to the prompt: with a real, simulated database dependency genuinely marked down, a real /healthz (liveness) endpoint genuinely still returned a real 200 — "the process itself is fine" — while a real /readyz (readiness) endpoint genuinely returned a real 503 — correctly signaling "don't route traffic here right now," without ever suggesting the process itself needs restarting.
  • This is the precise, direct fix for the prompt's scenario: liveness should check only whether the process itself is fundamentally broken (deadlocked, unresponsive) — verified above, it must not depend on external dependencies like the database — readiness should check real dependencies (verified above, exactly what caused the real 503) and is what an orchestrator uses to temporarily remove an instance from serving traffic, without restarting it, letting it automatically rejoin once /readyz genuinely starts passing again as the dependency recovers.
  • A precise answer names the real, complete failure mode the prompt's single-check design causes: unnecessary restarts during a transient, external dependency blip — genuinely counterproductive (a restart doesn't fix the database), versus the correct behavior verified above — the process stays running, genuinely ready to immediately resume serving traffic the instant the real dependency recovers, with zero restart needed at all.

Clarifying questions expected:

  • "Which specific dependencies should genuinely gate readiness — every downstream call this service ever makes, or only the ones without which it truly cannot function correctly at all?" — an overly broad readiness check can cause unnecessary traffic removal for a dependency that's actually optional for most requests.
  • "Does liveness need any real check at all beyond 'the HTTP server is responding,' or could a genuinely deadlocked process still technically respond to a trivial liveness ping while unable to process real requests?" — a real, deeper liveness design question for certain failure modes.

Code / implementation expected: Yes — real, distinct HTTP responses (a genuine 200 for liveness, a genuine 503 for readiness) from the identical, simultaneous real dependency outage is the concrete, convincing proof of exactly why the two checks must be separate, and what each one is actually for.

nodejsopshealth-checkkubernetes
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 and Kubernetes-adjacent interviews. Difficulty: Medium

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:. The real, distinct liveness/readiness responses below were

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

Real, distinct liveness and readiness responses to the identical simulated database outage
const express = require("express");
const app = express();
let dbConnected = true;

// LIVENESS: is the process itself alive? No dependency checks at all.
app.get("/healthz", (req, res) => res.status(200).json({ status: "alive" }));

// READINESS: is it ready to serve real traffic? Checks real dependencies.
app.get("/readyz", (req, res) => {
  if (!dbConnected) return res.status(503).json({ status: "not ready", reason: "database unreachable" });
  res.status(200).json({ status: "ready" });
});

// --- both healthy ---
// liveness: 200 { status: 'alive' }
// readiness: 200 { status: 'ready' }

dbConnected = false; // a real downstream dependency genuinely goes down

// --- process itself still fine, dependency down ---
// liveness: 200 { status: 'alive' }   <- genuinely still alive, no restart triggered
// readiness: 503 { status: 'not ready', reason: 'database unreachable' }  <- genuinely removed from routing
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 64 of 152 decoded in the Node.js track. One more won't hurt.

Back to track