On this page
How to Add Health Checks to Your App
Add liveness and readiness endpoints to a Python, Node, or Go app and wire them to your platform so failures trigger restarts and routing.
Quick answer
- Add /healthz (process alive) and /readyz (dependencies reachable) endpoints to your app.
- Use a Docker HEALTHCHECK or your platform’s probe config to consume them.
- Test that a failed dependency actually returns a non-200 so the probe is honest.
What endpoints do I add?
Two: /healthz returns 200 as long as the process responds, and /readyz returns 200 only when the dependencies it needs (database, cache, queue) are reachable, 503 otherwise. Keep both fast — a 1-second timeout on dependency checks. The framework snippets below show the minimal shape.
# FastAPI / Flask-style
@app.get("/readyz")
def readyz():
try:
db.session.execute(text("SELECT 1"))
return {"status": "ready"}
except Exception:
return JSONResponse({"status": "not ready"}, status_code=503)How do I wire it to Docker?
Add a HEALTHCHECK instruction to the Dockerfile so Docker (and platforms that read it) can probe the container. Use curl or a tiny script; check both that the endpoint responds and that readiness is true. Platforms like Railway and Fly.io also let you define a probe URL in config, which is often easier than relying on HEALTHCHECK alone.
FROM python:3.13-slim
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:8000/readyz', timeout=2).status==200 else 1)"
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]What does ‘it worked’ look like?
Stop the database and curl /readyz — it should return 503 within a second or two. Restart the database and it returns 200. In the platform dashboard, the container shows healthy, and if you kill the process the platform restarts it. If a probe returns 200 while the database is down, the check is not checking anything real — fix that before relying on it.
Where this bites vibecoders
This is a small, concrete task where AI assistants shine but still need supervision: they’ll happily write the endpoints, but may return 200 unconditionally, probe an external service (defeating the point), or set a start-period too short so the app gets restarted while still booting. The test at the end — break the database, watch the probe go 503 — is the part that catches those mistakes.
Where AI coding assistants get this wrong
- Health endpoint that always returns 200 regardless of actual state.
- Readiness check that probes an external API instead of the app’s own dependencies.
- HEALTHCHECK with no start-period, restarting a slow-booting app forever.
- Probe hitting an endpoint that itself does expensive work, spiking load.
Checklist
- Add /healthz and /readyz with cheap, real checks.
- Return 503 (not 200) when dependencies are unreachable.
- Configure HEALTHCHECK or platform probes with a start-period.
- Verify by breaking a dependency and watching the probe flip.
FAQ
How often should probes run?
Every 10-30 seconds is typical. Frequent probes catch failures faster but add load; every probe should be a cheap operation with a short timeout so the interval doesn’t matter much.
My app takes 20 seconds to start; will it be restarted in a loop?
Only if you misconfigure the start-period. Set the start-period (or initial delay) to longer than your slowest startup so the platform gives the app time to boot before counting failures.
Related topics
- What Is a Health Check?
- What Is Graceful Shutdown?
- What Is Uptime Monitoring?
- Why Does My App Ignore SIGTERM (and How Do I Fix It)?