Imagine you deploy an application to Kubernetes. The container starts successfully, but the application needs another 20 seconds to connect to the database and load its configuration. During that time, Kubernetes may send requests to the application before it is ready.
Now imagine the application starts normally but gets stuck later. The container is still running, yet it no longer responds to requests.
These are two different problems, and Kubernetes provides two different health checks to handle them: readiness probes and liveness probes.
A readiness probe tells Kubernetes whether an application is ready to receive traffic. A liveness probe helps Kubernetes decide whether a container should be restarted.
Choosing the wrong settings can cause real problems. An overly strict liveness probe may restart a healthy application during a temporary slowdown. A missing readiness probe may send requests to an application that cannot handle them yet.
In this article, we will explain how both probes work, how to configure them, and how to avoid common mistakes in production.
What Is a Kubernetes Readiness Probe?
A readiness probe checks whether a container is ready to handle requests.
If the probe fails, Kubernetes marks the container as not ready. For a Pod managed by a Service, this normally means the Pod is removed from the Service's ready endpoints, so it stops receiving regular traffic through that Service.
The container is not automatically restarted just because its readiness probe fails.
For example, an API might start its web server before it finishes loading required configuration or warming up a cache. A readiness probe can keep traffic away until the application is ready.
Here is a simple readiness probe:
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
Let's understand the settings:
httpGet sends an HTTP request to the application's health endpoint.
path specifies the endpoint Kubernetes checks.
port identifies the container port used for the check.
initialDelaySeconds delays the first probe after the container starts.
periodSeconds controls how often Kubernetes runs the probe.
timeoutSeconds sets the maximum time allowed for a probe.
failureThreshold determines how many consecutive failures are needed before the probe is considered failed.
In this example, Kubernetes checks /health/ready on port 8080. If the endpoint repeatedly fails, the container becomes unready and stops receiving normal Service traffic.
The readiness probe should answer one question: Can this application handle requests right now?
What Is a Kubernetes Liveness Probe?
A liveness probe checks whether an application is still working properly.
If the liveness probe fails enough times, Kubernetes restarts the container. This can help recover an application that has become stuck or cannot make progress.
For example, an application might enter a deadlocked state and stop responding to requests. The process still exists, but restarting the container may restore normal operation.
Here is a basic liveness probe:
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
This configuration checks /health/live every 10 seconds, allowing up to two seconds for each response. After three consecutive failures, Kubernetes considers the container unhealthy and restarts it.
The exact time before a restart depends on when the failures occur and how long each probe takes. It is not simply the failure threshold multiplied by the period in every situation.
A liveness probe should answer a different question from readiness: Is the application still functioning, or does it need to be restarted?
Readiness vs. Liveness: What Is the Difference?
Although both probes check application health, they have different effects.
Feature | Readiness probe | Liveness probe |
|---|
Main purpose | Decide whether the Pod should receive traffic | Decide whether the container should be restarted |
When it fails | The container becomes unready | The container may be restarted after repeated failures |
Stops normal Service traffic | Yes, when the Pod is no longer a ready endpoint | Usually as a consequence of the container becoming unhealthy or restarting |
Useful for startup delays | Yes | Not usually the best choice |
Useful for recovering a stuck process | Not by itself | Yes, if the check correctly identifies the failure |
Should depend on every external service | Only when the application truly cannot serve traffic without that dependency | Usually no |
A failed readiness probe does not mean the application must be restarted. It means the application should not receive normal traffic through the Service while it is unready.
A failed liveness probe has a stronger effect because it can trigger a restart. That is why liveness checks should be designed carefully.
Add Readiness and Liveness Probes to a Deployment
Let's configure both probes for an API running on port 8080.
apiVersion: apps/v1
kind: Deployment
metadata:
name: orders-api
spec:
replicas: 3
selector:
matchLabels:
app: orders-api
template:
metadata:
labels:
app: orders-api
spec:
containers:
- name: orders-api
image: example/orders-api:1.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health/ready
port: 8080
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
livenessProbe:
httpGet:
path: /health/live
port: 8080
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
This Deployment runs three replicas of the API and checks each container independently.
If one replica fails its readiness probe, Kubernetes can stop sending normal Service traffic to that replica while the other ready replicas continue handling requests.
If a replica repeatedly fails its liveness probe, Kubernetes may restart its container.
The image name, endpoints, and settings are examples. Your application must provide the configured health endpoints, and you should tune the probe settings based on how the application behaves under real conditions.
Create Health Endpoints That Check the Right Things
The probe settings are only useful if the application returns the correct result.
For example, an ASP.NET Core application can expose separate health endpoints for readiness and liveness.
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
Predicate = _ => false
});
app.MapHealthChecks("/health/ready");
app.Run();
In this example, /health/live does not run registered health checks. It reports whether the health-check endpoint can respond, which is useful as a basic liveness signal.
The /health/ready endpoint runs the registered health checks. However, because no dependency checks have been registered here, it does not yet verify database or other service readiness.
For a real application, register the readiness checks that match its requirements. For example, if the API cannot process requests without its database, you might add a database health check to the readiness endpoint.
Avoid automatically adding every external dependency to the liveness check. If a database is temporarily unavailable, restarting every API container may make recovery harder rather than easier.
Should a Liveness Probe Check the Database?
In most applications, a liveness probe should focus on whether the application process itself is healthy enough to continue running.
Suppose your database becomes unavailable for 30 seconds. If the liveness endpoint checks the database, every API replica may fail its liveness probe and restart.
The database may recover, but the API containers could now be restarting at the same time. This can create additional load and delay recovery.
A better separation is usually:
Liveness: Check whether the application can respond and has not entered a state that requires a restart.
Readiness: Check whether the application can currently handle its expected requests, including critical dependencies when necessary.
Startup: Allow enough time for the application to initialize before liveness and readiness checks begin.
There are exceptions. Some applications genuinely cannot make progress after a particular internal failure. In that case, a carefully designed liveness check can help, but it should not turn every temporary dependency problem into a restart.
Use a Startup Probe for Slow Applications
What if your application needs a long time to start?
For example, an application may need to load a large configuration file, initialize a runtime, or prepare local data before it can respond correctly.
Without a startup probe, an aggressive liveness probe might fail during normal initialization and restart the container before it has a chance to finish starting.
A startup probe gives the application more time to initialize. Kubernetes delays the regular liveness and readiness probes until the startup probe succeeds.
startupProbe:
httpGet:
path: /health/startup
port: 8080
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 30
livenessProbe:
httpGet:
path: /health/live
port: 8080
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: 8080
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3
With these settings, the startup probe allows a window of roughly 150 seconds for successful startup checks, subject to probe timing and execution details.
The startup endpoint must indicate that initialization is complete. If it reports success immediately while the application is still initializing, the startup probe will not provide the protection you need.
How to Choose the Right Probe Settings
There is no single set of values that works for every application. Start by understanding how long the application normally takes to start, how quickly its health endpoints respond, and how much time it needs to recover from temporary problems.
Set the timeout based on real response times
If the health endpoint normally responds in a few milliseconds, a two-second timeout may be reasonable. If the endpoint regularly takes longer, investigate why before increasing the timeout.
Health endpoints should generally be lightweight. Avoid making them perform expensive queries or large amounts of work.
Avoid an overly strict liveness probe
A very short timeout combined with a low failure threshold can restart containers during brief CPU pressure or temporary scheduling delays.
Allow enough room for normal variation, especially when the application runs under load.
Set readiness rules based on actual traffic needs
If the application cannot process requests until a required dependency is available, readiness should reflect that condition.
However, do not mark an application unready because of an optional feature that is temporarily unavailable if the application can still serve its main requests.
Test the settings under realistic conditions
Check what happens when the database becomes slow, the application takes longer to start, or a health endpoint stops responding.
These tests help reveal whether your probes recover from real failures or create unnecessary restarts.
Common Mistakes to Avoid
Mistake | Why it causes problems | Better approach |
|---|
Using the same endpoint for every probe without considering its purpose | Readiness and liveness may need different checks | Design each endpoint around its specific role |
Checking every dependency in the liveness probe | A temporary outage may restart all application replicas | Keep liveness focused on application health |
Setting very short timeouts | Healthy containers may be marked unhealthy during brief delays | Use measured response times and realistic thresholds |
Skipping readiness checks | Traffic may reach an application before it is ready | Add a readiness probe for services that receive traffic |
Forgetting slow startup times | Liveness may restart the application during normal initialization | Add a startup probe when needed |
Treating a successful probe as proof of full correctness | A health endpoint may respond while other features are broken | Combine probes with monitoring, logs, and application-level checks |
Best Practices for Production
Follow these guidelines when configuring Kubernetes health probes:
Give each probe a clear purpose. Readiness controls traffic, liveness helps recover stuck containers, and startup protects slow initialization.
Keep health endpoints lightweight. A health check should not become a source of extra load.
Use realistic thresholds. Base timeouts and failure counts on observed behavior rather than guesses.
Check only critical dependencies for readiness. Include dependencies that the application genuinely needs to serve requests.
Avoid dependency-heavy liveness checks. Temporary database or network problems should not automatically restart every application replica.
Use startup probes for slow initialization. Give applications time to start before applying liveness checks.
Test failure scenarios. Verify what happens during startup delays, dependency outages, and application hangs.
Monitor probe failures. Repeated readiness failures or restarts can point to performance problems, bad configuration, or an unhealthy dependency.
Conclusion
Kubernetes readiness and liveness probes solve different problems. A readiness probe tells Kubernetes whether a container should receive traffic, while a liveness probe helps Kubernetes decide whether a container needs to be restarted. A startup probe gives slow applications time to initialize.
Use readiness checks to keep traffic away from applications that cannot serve requests. Use liveness checks to detect failures that a restart can reasonably fix. Add startup probes when initialization takes longer than your normal health-check window.
The right settings depend on how your application behaves under load and during failures. Keep health endpoints simple, test them under realistic conditions, and monitor their results. This helps Kubernetes recover from genuine problems without repeatedly restarting healthy applications.
Join the conversation! Your thoughts help the community grow.