← Back to Blog

Kubernetes Health Probes: The Difference Between Alive and Ready

How liveness, readiness, and startup probes shape rollout safety and prevent Kubernetes from routing traffic to a broken application.

Cover image for Kubernetes Health Probes: The Difference Between Alive and Ready
KubernetesReliabilityObservabilityDevOps

A container process can be alive while the application is unable to serve traffic. Kubernetes health probes turn that distinction into scheduling behavior, but only when each probe answers one precise question.

Use readiness for traffic

Readiness should fail when the pod must stop receiving requests: a dependency is unavailable, migrations are running, or the application has not loaded its configuration. It should not restart the process.

The incident

A deployment looked healthy because every pod was Running, but users saw intermittent 502 responses. The application opened its port before database migrations finished, so the service sent traffic to pods that were alive and completely unready.

The first attempted fix increased the deployment delay. That reduced the frequency of the symptom but did not describe the application state. A fixed sleep is not a health model; it is a bet that the next deploy will be slower than the last one.

Use liveness for unrecoverable hangs

Liveness is for a process that is alive but cannot recover on its own. An aggressive liveness probe turns a slow dependency into a restart storm, so its timeout and failure threshold must reflect real startup and recovery behavior.

yaml
startupProbe:
  httpGet:
    path: /health/startup
    port: http
  failureThreshold: 30
  periodSeconds: 5
readinessProbe:
  httpGet:
    path: /health/ready
    port: http
  periodSeconds: 5
livenessProbe:
  httpGet:
    path: /health/live
    port: http
  failureThreshold: 3
  periodSeconds: 10

Test probes during failure

Stop a dependency, delay startup, exhaust connections, and deploy a bad configuration in a test environment. The expected result is not merely a green pod: traffic should drain, restarts should be bounded, and rollout progress should remain observable.

The resolution

We split one overloaded health endpoint into startup, readiness, and liveness checks. Readiness verified dependencies needed to serve requests, startup allowed the application time to initialize, and liveness checked only for a process that had stopped making progress. Rollouts became slower by a few seconds and much safer.

We verified the change by killing the database connection, delaying the application boot, and forcing a bad configuration into staging. In each case, traffic stopped before the pod was restarted, and the rollout reported the real failure instead of presenting a green but useless status.

Keep the three decisions independent

A startup probe temporarily gates the other probes while initialization runs. Readiness decides whether this replica should receive new traffic; liveness should detect a process that is stuck and cannot recover. Keep liveness local and cheap rather than making every pod restart when a shared database has a bad afternoon. Also align terminationGracePeriodSeconds and any preStop work with the time the application needs to drain requests.

Startup gates initialization, readiness controls routing, and liveness controls restart; each signal has a different consequence.
Startup gates initialization, readiness controls routing, and liveness controls restart; each signal has a different consequence.

If all three probes answer the same question, the cluster has three sensors and one blind spot.

Probe design in one sentence

A health endpoint is an operational contract. Keep it cheap, deterministic, and explicit about what the platform should do next.

← Back to BlogHome