On this page
What Is a Health Check?
A health check is an endpoint that reports whether your app is alive and ready. Learn the difference between liveness and readiness and why both matter.
Quick answer
- A health check is an endpoint (usually /healthz) that reports whether your service is alive and able to serve traffic.
- Liveness says ‘the process is running’; readiness says ‘it can handle requests right now’.
- Load balancers and orchestrators use health checks to stop sending traffic to broken instances.
What is the difference between liveness and readiness?
A liveness check asks ‘is the process still alive?’ and restarts the container when it fails. A readiness check asks ‘can this instance accept traffic?’ and removes the instance from rotation when it fails, without restarting it. They answer different questions: a service warming up a cache or waiting on a database is alive but not ready; a deadlocked process is neither.
What should a health check actually check?
Keep it honest but cheap: verify the database connection, any queue connection, and that the process responds — but don’t run expensive operations on every probe. A common pattern is /healthz returning 200 with a tiny JSON body, plus a /readyz that performs quick dependency checks with a short timeout. If a check does heavy work, it becomes a self-inflicted load spike when an orchestrator probes it every few seconds.
# FastAPI example
@app.get("/healthz")
def healthz():
return {"status": "ok"}
@app.get("/readyz")
def readyz():
db_ok = db.ping(timeout=1)
return {"status": "ready" if db_ok else "not ready"}, 200 if db_ok else 503Where do health checks get used?
Load balancers poll them to remove unhealthy instances from rotation. Kubernetes livenessProbe/readinessProbe runs them inside the container. Managed platforms like Fly.io and Railway use them to restart or reschedule apps. Uptime monitors also hit them from outside — a health check is the natural endpoint for ‘is the site actually up’ alerting.
Where this bites vibecoders
AI assistants rarely generate health check endpoints unless asked, so a vibecoder’s first deploy on a platform with a ‘restart on failure’ toggle finds the toggle doesn’t work — there’s no endpoint to probe. Worse, some assistants generate readiness checks that check nothing real, returning 200 even when the database is down. One honest /readyz endpoint turns a platform’s restart and load-balancing features from decoration into working safety nets.
Where AI coding assistants get this wrong
- Returning 200 unconditionally from a ‘health’ endpoint, so it proves nothing.
- Putting heavy work (full queries, external calls) in the probe path, spiking load.
- Confusing liveness and readiness: restarting a service that just isn’t ready yet.
- Not adding a health endpoint at all, so platforms and monitors have nothing to probe.
Checklist
- Expose /healthz (alive) and /readyz (dependencies reachable) endpoints.
- Keep probes cheap and fast with a short timeout.
- Wire readiness to the load balancer and liveness to the process supervisor.
- Point an uptime monitor at the health endpoint for external alerting.
FAQ
What status code should a health check return?
200 when healthy, and a 5xx code (usually 503) when not ready. Monitoring and orchestration tooling keys off status codes, so returning 200 for a broken service defeats the purpose.
Should health checks require authentication?
Generally no — orchestrators and monitors need unauthenticated access to probe. Keep the endpoint read-only and leak nothing sensitive; if your platform requires auth for probes, configure that path explicitly.
Related topics
- How to Add Health Checks to Your App
- What Is Uptime Monitoring?
- How to Get Alerted When Your Site Goes Down
- What Is Graceful Shutdown?
- What Is a Reverse Proxy?
- Why Does My App Ignore SIGTERM (and How Do I Fix It)?