Liveness Probe vs Readiness Probe
Key Differences in Kubernetes
A liveness probe detects if a container is stuck or deadlocked and restarts it to recover. A readiness probe detects if a container is ready to handle traffic and adds or removes it from Service endpoints. Liveness answers 'is this container alive?' while readiness answers 'should this container receive requests?'
Side-by-Side Comparison
| Dimension | Liveness Probe | Readiness Probe |
|---|---|---|
| Purpose | Detects if the container is in a broken state (deadlock, hang) | Detects if the container is ready to accept traffic |
| Action on Failure | Restarts the container (kills and recreates it) | Removes the Pod from Service endpoints (stops sending traffic) |
| Action on Success | No action — container continues running | Adds the Pod back to Service endpoints |
| Default Behavior | If not configured, container is assumed alive as long as it is running | If not configured, container is assumed ready as soon as it starts |
| Typical Check | HTTP GET /healthz, TCP socket, or exec command | HTTP GET /ready, checking dependencies, cache warmth |
| When It Matters | Application enters an unrecoverable state (thread deadlock, resource exhaustion) | Application is starting up, warming caches, or temporarily overloaded |
| Startup Interaction | Should use startupProbe for slow-starting apps to avoid premature restarts | Readiness naturally handles startup — Pod not added to endpoints until ready |
Detailed Breakdown
Liveness Probe
A liveness probe tells Kubernetes whether the container is still running properly. If it fails, the kubelet kills the container and the restart policy determines what happens next.
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: app
image: my-app:1.0.0
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
successThreshold: 1
This configuration:
- Waits 15 seconds after the container starts before the first check
- Checks
/healthzevery 10 seconds - Considers the probe failed if no response within 3 seconds
- Restarts the container after 3 consecutive failures
The /healthz endpoint should check for conditions that only a restart can fix:
@app.get("/healthz")
def healthz():
# Check for deadlock, thread pool exhaustion, etc.
if thread_pool.is_deadlocked():
return Response(status_code=500)
return Response(status_code=200)
Readiness Probe
A readiness probe tells Kubernetes whether the container is ready to receive traffic. If it fails, the Pod's IP is removed from all Service endpoints.
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: app
image: my-app:1.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3
successThreshold: 1
The /ready endpoint should check whether the application can actually handle requests:
@app.get("/ready")
def ready():
# Check dependencies and initialization
if not cache.is_loaded():
return Response(status_code=503)
if not db.is_connected():
return Response(status_code=503)
return Response(status_code=200)
The Critical Difference in Action
Consider a Java application that takes 60 seconds to load its cache:
Without probes: Kubernetes adds the Pod to Service endpoints immediately. Clients hit the Pod before the cache is loaded, getting errors or slow responses.
With readiness probe only: The Pod is not added to Service endpoints until the cache is loaded. Clients are shielded from the startup period.
With liveness probe only (dangerous!): If initialDelaySeconds is too short, the liveness probe fires before the cache loads, considers the app unhealthy, and restarts it — creating a restart loop.
With both probes (correct): The readiness probe holds traffic until the app is ready. The liveness probe monitors for deadlocks during normal operation.
Startup Probe — The Third Probe
For slow-starting applications, a startup probe prevents the liveness probe from killing the container during startup:
spec:
containers:
- name: app
image: my-app:1.0.0
startupProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 5
failureThreshold: 30 # 30 * 5 = 150 seconds to start
livenessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
failureThreshold: 3
The startup probe runs first. The liveness and readiness probes are disabled until the startup probe succeeds. This gives the application up to 150 seconds to start (30 checks x 5 seconds) without risk of the liveness probe restarting it.
Probe Types
All three probes support the same check mechanisms:
# HTTP GET — most common for web applications
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Health-Check
value: kubernetes
# TCP Socket — for services that don't serve HTTP
livenessProbe:
tcpSocket:
port: 5432
# Exec Command — runs a command inside the container
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
# gRPC — for gRPC services (Kubernetes 1.27+)
livenessProbe:
grpc:
port: 50051
service: my.health.v1.Health
Common Anti-Patterns
Anti-pattern 1: Liveness probe checks external dependencies
# BAD — if the database is down, all Pods restart
# Restarting won't fix the database
livenessProbe:
httpGet:
path: /healthz # This endpoint checks database connectivity
port: 8080
Liveness probes should only check the container's internal health. If the database is down, restarting the app will not help — use a readiness probe to stop traffic instead.
Anti-pattern 2: Same endpoint for liveness and readiness
# RISKY — if /health checks dependencies, a dependency outage
# causes both probes to fail, restarting all Pods
livenessProbe:
httpGet:
path: /health
port: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
Use separate endpoints: /healthz for liveness (internal health only) and /ready for readiness (includes dependency checks).
Anti-pattern 3: Too aggressive liveness probe
# BAD — restarts after just 2 seconds of unresponsiveness
livenessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 1
failureThreshold: 2
timeoutSeconds: 1
A brief GC pause or CPU spike triggers a restart. Set conservative thresholds — a few seconds of unresponsiveness is usually not worth a restart.
Best Practices
- Always configure readiness probes — they protect against sending traffic to unready Pods during deployments and scaling events
- Be conservative with liveness probes — false positives cause unnecessary restarts that can cascade into outages
- Use startup probes for slow starters — Java applications, ML model loading, or large cache warm-up
- Separate liveness and readiness endpoints — liveness checks internal health, readiness checks dependencies
- Set appropriate thresholds —
failureThreshold: 3withperiodSeconds: 10gives 30 seconds before action, which is usually appropriate
Use Liveness Probe when...
- •Your application can get into a deadlocked or hung state
- •You want automatic recovery from unrecoverable failures
- •The application has known failure modes that only a restart can fix
- •You're running long-lived processes that may become unresponsive
Use Readiness Probe when...
- •Your application needs time to warm up before handling traffic
- •The application depends on external services that may be temporarily unavailable
- •You want to gracefully drain traffic during deployments
- •You want to implement circuit-breaker patterns
- •Your application loads data or caches on startup
Model Interview Answer
“Liveness and readiness probes serve different purposes. A liveness probe checks if the container is still functioning — if it fails, Kubernetes restarts the container. This handles deadlocks, infinite loops, and other unrecoverable states. A readiness probe checks if the container is ready to handle requests — if it fails, Kubernetes removes the Pod from Service endpoints so it stops receiving traffic, but does not restart it. A common example: during startup, a Java application loading a large cache would fail readiness (not yet ready) but pass liveness (still alive). There is also a startup probe for slow-starting applications — it runs first and disables liveness checks until the app has started, preventing premature restarts.”