Three probe types (Kubernetes model)

  • Liveness — is this process alive and not deadlocked? Failure restarts the container. Should only fail on truly unrecoverable states.
  • Readiness — is this instance ready to serve traffic? Failure removes it from the load balancer. Appropriate to fail when a dependency (DB, cache) is temporarily unavailable.
  • Startup — did this application finish starting? Disables liveness and readiness probes until startup succeeds. For slow-starting apps (JVM warm-up, cache pre-warming).

Implementation

// Liveness — minimal check
GET /health/live → 200 OK {"status": "ok"}

// Readiness — check dependencies
GET /health/ready
→ check db.ping(), redis.ping()
→ 200 {"status": "ok", "checks": {"db": "ok", "cache": "ok"}}
→ 503 {"status": "degraded", "checks": {"db": "ok", "cache": "timeout"}}

Common mistakes

  • Making liveness check dependencies — a slow DB makes Kubernetes restart healthy pods in a cascade.
  • Returning 200 always — defeats the purpose entirely.
  • Expensive operations in health checks — health endpoints are called every 10 seconds; they must be fast.