Kubernetes Liveness, Readiness and Startup Probes Explained
Practice4 minInnovialabs editorial team
In short
Liveness restarts a stuck container, readiness removes a pod from traffic while it cannot serve, and startup gives slow apps time to boot before the other two begin — keep liveness checks shallow and never make them depend on the database.
The short answer
Kubernetes has three probes, and each controls a different action:
| Probe | Question it asks | What happens on failure |
|---|---|---|
| Liveness | Is the process stuck beyond repair? | The kubelet restarts the container |
| Readiness | Can this pod serve requests right now? | The pod is removed from Service endpoints, no restart |
| Startup | Has the app finished starting? | Liveness and readiness wait; if it never succeeds, the container is restarted |
Without probes, Kubernetes only knows whether the process is running. A deadlocked server or an app still warming its cache would keep receiving traffic.
Three ways to check
HTTP — the most common choice for web services. Any status from 200 to 399 counts as success.
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
failureThreshold: 3
TCP — only checks that the port accepts connections. Useful for databases, brokers and non-HTTP services.
livenessProbe:
tcpSocket:
port: 5432
periodSeconds: 10
Exec — runs a command inside the container; exit code 0 means healthy.
livenessProbe:
exec:
command: ["sh", "-c", "test -f /tmp/healthy"]
periodSeconds: 10
Kubernetes also supports gRPC probes for services that implement the standard gRPC health protocol. Exec probes start a process on every check, so keep them cheap.
A sensible full setup
containers:
- name: api
image: registry.example.com/api:2.1.0
ports:
- containerPort: 8080
startupProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 5
failureThreshold: 30
livenessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2
Here the startup probe allows up to 30 × 5 = 150 seconds to boot. After it succeeds, liveness and readiness take over.
What each endpoint should check
- /healthz (liveness): only the process itself. Can it respond at all? Is the main loop alive? No external calls.
- /ready (readiness): whether this instance can do useful work: warmed up, not draining, critical local resources available. Checking a dependency here is acceptable if the pod truly cannot serve without it, but think about what happens when all pods fail at once.
- Startup: often the same endpoint as liveness, just with a generous failure budget.
Tuning delays and thresholds
The main fields:
periodSeconds— how often to check.timeoutSeconds— how long to wait for a response. The default is short, so slow endpoints fail under load.failureThreshold— consecutive failures before acting.successThreshold— consecutive successes to recover (must be 1 for liveness and startup).initialDelaySeconds— wait before the first check. With a startup probe you rarely need it.
Rough time to react is periodSeconds × failureThreshold. Make liveness tolerant (a restart is expensive) and readiness quick (removing traffic is cheap and reversible).
Common mistakes
- Checking the database in a liveness probe. When the database has a hiccup, every pod fails liveness and restarts at the same time. Restarts do not fix the database and add load when it comes back.
- Same endpoint and thresholds for liveness and readiness. You lose the distinction between "stop sending traffic" and "restart me".
- Huge
initialDelaySecondsinstead of a startup probe. It slows recovery of every restart, not just the first boot. - Timeouts that are too tight, so a busy but healthy pod gets killed during peak load, which makes the load worse.
- Heavy health handlers that query many services or allocate a lot of memory.
- No readiness probe at all, so new pods get traffic before they are ready during a rolling update.