# Health check design: how do I separate Liveness and Readiness?

> Keep liveness dependency-free and check dependencies in readiness with a cached probe, since liveness restarts the pod while readiness only sheds traffic.

- Asked: 2026-06-03
- Answered: 2026-06-06
- Asked by: Eren
- Tags: dayaniklilik, altyapi, kubernetes
- Source: https://muhammetsafak.com/just-ask/health-check-design-liveness-vs-readiness/
- Language: en-US
- Author: Muhammet Şafak

---
**Question:** We're going to write `/health` endpoints for containers behind Kubernetes / a Load Balancer. But just returning `{status:ok}` doesn't show whether the app is actually working — if the DB connection is down but HTTP is up, it's misleading.

Architecturally, how do I separate Liveness and Readiness? And what should I watch out for so these endpoints don't overload the DB?


Short answer: a static `{status:ok}` only proves the HTTP server is up, not that the app can actually **serve**. The fix is to separate two different questions: "is it alive?" and "is it ready?".

## Short answer

The real issue is this: Liveness and Readiness measure different things, and if you mix them up you shoot yourself in the foot — especially if you put the dependency check on the wrong probe. Readiness' "pull me out of rotation but don't kill me" behaviour is the same traffic-draining logic you need when a pod shuts down during autoscaling; I covered that side in [the SIGTERM graceful shutdown answer](/just-ask/graceful-shutdown-on-sigterm-for-autoscaled-apis/).

## Why

1. **The two probes map to different consequences.** If liveness fails, Kubernetes **restarts** the pod; if readiness fails, it just **stops traffic**. This distinction is critical: on a temporary dependency issue you don't want to restart the pod, you only want to stop traffic.
2. **Putting a dependency on liveness creates a restart loop.** A momentary DB blip throws all your healthy pods into an endless restart loop — even though nothing is wrong with the processes themselves.
3. **Probe cost multiplies by replica count.** If every replica's probe runs a real query against Postgres every few seconds, 50 pods × constant probes = you take down your own database.

## What to do

1. **Keep liveness cheap and dependency-free.** **Don't check** the DB, cache or queue here. Liveness should only ask "is the process responding?".
2. **Check the critical dependencies in readiness.** Check the dependencies you need to serve here, like the DB, cache and queue. When a dependency goes down, let the Load Balancer pull the pod out of rotation — but **without killing it**. When the dependency comes back, the pod re-enters traffic.
3. **Run readiness with a short timeout and cache its result.** **Cache** the result for a few seconds, and check only what you truly need to serve.
4. **Add a startup probe for slow boots.** If your app boots slowly, use a separate startup probe so liveness doesn't kill the pod while the app is still coming up.

**Bottom line:** I'd make liveness cheap and dependency-free, and readiness dependency-aware but cached. The golden rule: never let your probes DDoS the database. I separately discuss whether you really need Kubernetes on sade.dev; but if you don't make this distinction, the smallest DB tremor will shake your whole cluster.

## Related Reading

- [Signals That a System Has Grown Too Complex](https://sade.dev/en/journal/signals-of-an-over-complex-system) — sade.dev
- [Disaster recovery: how do I design an active-passive scenario around RTO and RPO?](https://muhammetsafak.com/just-ask/disaster-recovery-strategy-setting-rto-and-rpo/) — Just Ask
- [How do I prevent log storms and disk-full outages?](https://muhammetsafak.com/just-ask/preventing-log-storms-and-disk-full-outages/) — Just Ask
- [Should I define the healthcheck in the Dockerfile or leave it to Kubernetes probes?](https://muhammetsafak.com/just-ask/should-i-define-the-healthcheck-in-the-dockerfile-or-leave-it/) — Just Ask
