Liveness Probes in Kubernetes
A friendly, step-by-step guide to how Kubernetes checks that your application is truly alive, not just switched on: what a liveness probe is, how it works, how to tune it, and how to avoid the mistakes that cause restart storms.
Imagine a night guard in a shop. Every hour the manager phones the guard’s desk. If the guard answers, all is well. If nobody answers for a long time, the manager does not simply assume the guard is fine because the lights in the guard room are on. The manager sends someone to check, and if needed, wakes the guard up or replaces them.
Kubernetes faces the same problem with your applications. A program can be “running” in the eyes of the computer, with its process alive and its lights on, while inside it is completely stuck: frozen in a deadlock, out of worker threads, or spinning in a loop, unable to answer a single customer. From the outside, everything looks normal. Inside, nobody is home.
The tool that catches this is called a liveness probe. In this guide we will build the idea from zero, one small step at a time. Every new word is explained the first time it appears, and every big idea comes with an everyday comparison so it sticks.
1What Is a Liveness Probe?
To understand a liveness probe we need a handful of simple words: container, pod, kubelet, probe and restart.
Container
A container is a small sealed box that holds an application and everything it needs to run. Kubernetes starts and stops containers for you.
Pod
A pod is the smallest unit Kubernetes runs. It holds one or more containers that live and work together on the same computer.
Kubelet
The kubelet is the agent that runs on every computer in the cluster. It starts the containers on its computer, watches them, and reports back to the cluster’s control centre.
Probe
A probe is a small, regular health check that the kubelet performs on a container. Think of it as a doctor tapping your knee to see whether you respond.
Restart
A restart means stopping a container and starting a fresh copy of it, in the same pod, on the same computer. It is Kubernetes’ way of saying “turn it off and on again”.
Liveness
Liveness means “is this container still able to do its job at all?”. A container that is stuck for good is not alive in this sense, even though its process still exists.
So what exactly is a liveness probe?
A liveness probe is a rule you attach to a container that tells the kubelet how to check, again and again, whether the container is still alive. If the check keeps failing, the kubelet decides that the container is beyond saving and restarts it.
The purpose is very specific. A liveness probe is not about sending traffic, or about slow starts, or about a temporary hiccup. It is about detecting the situations where the only sensible cure is a restart, and then doing that restart automatically, at any hour, without a human being woken up.
Think of a hospital heart monitor beside a patient’s bed. It does not treat the patient. It only watches for a pulse, and if the pulse stops for too long, it raises the alarm so the team can act. A liveness probe is the heart monitor of a container. In Kubernetes the “team” is the kubelet, and the action it takes is to restart the container.
A short history
Google released Kubernetes as open source in 2014. Health checking was part of the thinking from the very beginning, because Google’s own internal systems had long relied on automatically replacing broken programs. The liveness probe was one of the earliest features.
Later, two companions were added. The readiness probe decides whether a container should receive traffic. The startup probe, which became stable in the version 1.20 era, protects slow-starting programs. Together the three make up the family of Kubernetes health checks, and we will see how they differ.
The question a liveness probe answers is “Should Kubernetes restart this container?” Nothing more. If you keep that one sentence in mind, most design decisions in this guide will feel natural.
2The Problem Liveness Probes Solve
Kubernetes already restarts containers that crash. So why do we need to teach it to notice anything else?
What Kubernetes knows without help
By default, Kubernetes watches one simple fact: is the main process of the container still running? If the program exits, whether by crashing or by finishing, Kubernetes notices at once and, depending on the pod’s restart rule, starts it again. This handles loud failures very well.
But many failures are silent. The process is still there, breathing, yet it cannot do useful work. Here are some real examples that engineers meet again and again.
Deadlock
Two parts of the program each wait for the other forever, like two people who both insist “after you” at a door and never pass through. The process is alive but frozen.
Exhausted workers
A web server has a fixed team of worker threads. If all of them get stuck waiting on something slow, new requests queue up and nobody is served.
Infinite loop
A bug makes the program spin at full speed doing nothing useful. It uses lots of processor time and answers no one.
Broken internal state
A lost connection or corrupted cache leaves the program running but permanently unable to perform its task, and it never repairs itself.
Without a liveness probe, such a container stays in this half-dead state until a human notices the complaints and restarts it by hand. That could take minutes or hours. Every request sent to it fails in the meantime.
flowchart TB
subgraph WITHOUT["Without a liveness probe"]
direction LR
A1["Application freezes but the process stays alive"] --> A2["Kubernetes sees a running process"]
A2 --> A3["Customers get errors or timeouts"]
A3 --> A4["A human finally notices and restarts it"]
end
subgraph WITH["With a liveness probe"]
direction LR
B1["Application freezes but the process stays alive"] --> B2["Probe stops getting answers"]
B2 --> B3["Kubelet restarts the container automatically"]
B3 --> B4["Service recovers in seconds or minutes"]
end
A shop assistant who has fallen asleep at the counter is still “present” at work. If the manager only checks whether the assistant is in the building, everything looks fine. A liveness probe is the manager tapping the assistant’s shoulder every ten seconds and asking, “Are you with me?”. No answer three times in a row means it is time to wake them up, or send in a replacement.
| Situation | Default Kubernetes behaviour | With a liveness probe |
|---|---|---|
| Program crashes and exits | Restarts it | Same, the probe is not needed |
| Program finishes normally | Restarts or completes, depending on the pod rules | Same |
| Program deadlocks and stays alive | Does nothing | Detects the silence and restarts it |
| Program runs out of worker threads | Does nothing | Restarts it if the health check stops answering |
| Program is slow but healthy | Does nothing | Should do nothing, if the probe is tuned well |
A liveness probe is a strong medicine. A wrong probe can restart perfectly healthy programs again and again. Not every application needs one, and a badly designed one is worse than none. This guide spends a lot of time on that danger.
3Core Concepts
A probe has two decisions to make: how to check, and how patient to be. Learn these building blocks and every probe you meet will make sense.
The four ways to check
The kubelet can perform four kinds of check. You choose one per probe, depending on what your application offers.
HTTP check
The kubelet makes a web request to an address and port inside the container. Any answer with a success or redirect code, from 200 up to but not including 400, counts as healthy. Anything else, or no answer in time, counts as a failure.
TCP check
The kubelet simply tries to open a network connection to a port. If the connection opens, the check passes. It is ideal for programs that do not speak the web language.
Exec check
The kubelet runs a small command inside the container. If the command finishes with exit code zero, the check passes. Any other code is a failure.
gRPC check
For programs that use gRPC, a modern fast way for services to talk, the kubelet can call the standard health-checking service that gRPC defines.
The four checks are four ways of checking on a friend. The HTTP check is sending a text and reading their reply. The TCP check is ringing the doorbell and seeing whether the door opens. The exec check is asking them to perform a small task and looking at the result. The gRPC check is using a special agreed phone line just for “are you okay?” calls.
The settings that control patience
How often to check, how long to wait, and how many failures to tolerate are all adjustable. These settings have sensible defaults, but understanding them is the key to good probes.
| Setting | Meaning | Default |
|---|---|---|
initialDelaySeconds | How long to wait after the container starts before the first check | 0 seconds |
periodSeconds | How often to run the check | 10 seconds |
timeoutSeconds | How long to wait for an answer before calling the check failed | 1 second |
failureThreshold | How many failures in a row before the kubelet acts | 3 |
successThreshold | How many successes in a row count as recovered. For liveness this must be 1 | 1 |
terminationGracePeriodSeconds | Optional extra setting: how long a container gets to shut down politely when a probe fails | Uses the pod’s own value |
From these settings we can work out an important number: how long a frozen container survives before it is restarted. Roughly, it is the period multiplied by the failure threshold, plus the time the last check waits for its timeout. With the defaults of a ten-second period and three failures, that is about thirty seconds, plus a moment.
Three probes, three jobs
| Probe | Question it answers | What happens on failure |
|---|---|---|
| Liveness | Is the container stuck for good? | The container is killed and restarted |
| Readiness | Is the container ready to receive traffic right now? | The pod is removed from the service’s list of receivers, but not restarted |
| Startup | Has the container finished starting up? | Other probes stay switched off until it passes. If it never passes in time, the container is restarted |
Picture a restaurant kitchen. The startup probe asks, “Has the chef finished setting up the stove?”. The readiness probe asks, “Can the chef take another order right now?”. The liveness probe asks, “Is the chef still conscious?”. Only the last question leads to calling an ambulance. The second just makes the waiter hold new orders for a moment.
The restart happens to the container, not the whole pod. The pod keeps its network address and its attached volumes. Files kept in the pod’s shared scratch space survive, but anything the container wrote to its own layer is lost.
4Architecture and Components
Probes are not run by some distant central system. They are run right next to your container, by a small agent on the same computer. Let us meet the players.
flowchart LR
SPEC["Pod definition with probe settings"] --> API["Kubernetes API Server"]
API --> KUB["Kubelet on the node"]
KUB -->|"HTTP request"| APP["Container: your application"]
KUB -->|"TCP connection attempt"| APP
KUB -->|"Run a command"| APP
KUB -->|"gRPC health call"| APP
KUB -->|"Too many failures"| RT["Container runtime"]
RT -->|"Stop and start the container"| APP
KUB -->|"Events and status"| API
Piece by piece
The pod definition is where you write the probe rules. Each container in the pod can have its own liveness, readiness and startup probes. The definition is stored in the cluster through the API server, the front desk of Kubernetes.
The kubelet reads the definition of every pod assigned to its computer and sets up a small timer-driven worker for each probe. This is important: the checks come from the same computer as the container, not from a faraway machine. That keeps them fast and means they keep working even if the computer loses contact with the control centre.
The container runtime is the software that actually starts and stops containers. The kubelet does not kill containers itself. It asks the runtime to stop the old one and start a new one.
Your application must offer something to check. That may be a web address such as a health endpoint, a listening network port, a command that can be run, or a gRPC health service. The quality of your probe depends entirely on how well this piece is designed.
The API server and events receive the kubelet’s reports. When a probe fails, the kubelet records an event such as “Liveness probe failed”, and after the restart it updates the restart counter. Those records are how you, as a human, learn what happened.
Think of a security guard patrolling a warehouse. The guard (kubelet) lives in the building, so he checks every room on a regular round without needing to phone the head office. When he finds a room with a problem, he calls the maintenance crew (container runtime) to fix it, and writes a note in the logbook (events) for the manager to read tomorrow.
Because the kubelet runs the probe, an HTTP check comes from the computer’s own network, not from another pod. Some strict network rules can accidentally block it. If a healthy application keeps failing its probe right after a network policy change, check that the kubelet’s traffic is allowed.
5How a Liveness Probe Works Internally
Here is what the kubelet does, second by second, after your container starts.
flowchart TD
A["Timer fires every period"] --> B["Kubelet runs the check"]
B --> C{"Did it succeed before the timeout?"}
C -->|"Yes"| D["Reset the failure count to zero"]
C -->|"No"| E["Add one to the failure count"]
E --> F{"Has the count reached the threshold?"}
F -->|"No"| A
F -->|"Yes"| G["Kill the container and start a new one"]
D --> A
G --> H["Restart counter goes up by one"]
H --> A
Wait for the initial delay
After the container starts, the kubelet waits for the configured initial delay. If a startup probe exists, the liveness probe stays switched off until the startup probe succeeds.
Check on a timer
Every period, the kubelet performs the chosen check. It waits for an answer up to the timeout. A slow answer that arrives too late counts as a failure.
Count consecutive failures
One failure does not cause a restart. Only failures in a row count. A single success resets the count to zero, which forgives temporary hiccups.
Reach the threshold
When the number of consecutive failures reaches the failure threshold, the kubelet decides the container is dead and starts the restart process.
Stop politely, then firmly
The container is first asked to shut down with a termination signal, which gives a well-written application the chance to close files and connections. If it does not stop within the grace period, it is forced to stop.
Start a fresh copy
The runtime starts a new container from the same image. The pod stays put; only the container is replaced. If containers keep failing, Kubernetes waits longer between restarts.
Doing the arithmetic
Suppose the period is ten seconds, the timeout is one second, and the failure threshold is three. A container freezes just after a successful check. The next check, ten seconds later, fails after waiting one second. That is failure one. The second failing check comes ten seconds after that, and the third ten seconds later. The restart begins about thirty seconds after the container froze, and up to ten seconds either side depending on exact timing.
If your business can accept thirty seconds of trouble, these defaults are fine. If not, you shorten the period. If your application often pauses for ten seconds during heavy work, you lengthen the timeout or raise the threshold, otherwise healthy but busy containers will be killed by mistake.
The restart backoff
If a container keeps failing and restarting, Kubernetes does not restart it instantly forever. It inserts a growing delay between attempts: about ten seconds, then twenty, then forty, and so on, up to a maximum of five minutes. If the container then runs happily for about ten minutes, the delay resets. During the waiting time, the pod shows the status CrashLoopBackOff. This protects the computer from wasting effort on a container that will not recover.
Imagine trying to start a cold car engine. The first time it fails, you try again at once. After several failures you wait longer between tries, so you do not flatten the battery. The backoff delay is that sensible waiting.
A very high number in the RESTARTS column, next to a young age, often means a probe is killing containers that are actually healthy. Look at the pod’s events and see whether the reason is “liveness probe failed” rather than a real crash.
Shutdown timing and the grace period
When the kubelet decides to restart a container, it does not pull the plug instantly. It first sends a polite termination signal and then waits for the grace period, which is thirty seconds unless changed. A well-written program uses this time to finish the request it is handling, close its files and say goodbye to its connections. If the container is still running after the grace period, it is stopped by force.
This matters for liveness probes in a special way. A container that has frozen may never react to the polite signal, so the restart takes the full grace period before the force-stop arrives. If your grace period is a long one hundred and twenty seconds, a frozen container could be lingering for two minutes after the probe decided it was dead. Newer versions of Kubernetes let you set a shorter grace period just for probe-triggered restarts, so frozen containers are replaced swiftly while normal shutdowns stay gentle.
6Data Flow and Lifecycle
Now let us follow one container through its whole life, from start-up, through healthy service, to a freeze and a restart.
sequenceDiagram
participant C as Container
participant K as Kubelet
participant S as Service Endpoints
K->>C: Start the container
K->>C: Startup probe repeated until it passes
C-->>K: Startup probe passes
K->>C: Begin liveness and readiness probes
C-->>K: Readiness passes
K->>S: Pod is added to the list of receivers
Note over C: The application freezes
K->>C: Liveness check gets no answer
K->>C: Liveness check gets no answer again
K->>C: Third failure in a row
K->>C: Stop the container and start a fresh one
K->>S: Pod removed until ready again
The stages of life
Starting
The container is launched. Liveness and readiness checks are held back while the startup probe, if any, is still working.
Started
The startup probe has passed, or there was none. Liveness and readiness checks begin their regular rounds.
Serving
Readiness passes, so the pod receives traffic. Liveness passes quietly in the background every few seconds.
Stuck
Something breaks inside. The process lives, but liveness checks start failing.
Restarting
The threshold is reached. The container is stopped and replaced. The restart counter grows by one.
Recovered or backed off
The new container passes its probes and resumes service, or it keeps failing and the backoff delay grows.
What a restart keeps and what it loses
A restart replaces only the container. The pod, its name, its network address, its attached storage volumes and the contents of its shared scratch folders all remain. What is lost is everything inside the old container’s memory and its own writable layer. Connections open to the old container are cut, which is why clients should be ready to retry.
This is one reason liveness probes suit stateless programs so well. A stateless program keeps nothing important in memory, so being restarted costs only a few seconds. A program that holds a lot of unsaved data in memory needs more care, because a wrongly triggered restart could lose that data.
How you see it happening
When a liveness probe fails, the kubelet writes an event to the pod, along the lines of “Liveness probe failed” followed by the reason, such as an HTTP status code or a timeout. When the threshold is reached, another event records that the container failed its probe and will be restarted. The pod list shows the RESTARTS number growing. The pod’s detailed description also shows the last state of the container, including the reason and exit code of the previous run.
Exit code 137 is a common one to recognise. It means the container was force-stopped with a kill signal after it failed to shut down politely. Exit code 143 means it stopped in response to the polite termination signal.
Restarting a container is like a shop assistant taking a five-minute break and being replaced by a fresh colleague at the same counter. The counter, the till, and the customer queue are unchanged. What is lost is the first assistant’s unwritten notes in their head.
The liveness probe does not remove a pod from traffic by itself. During the seconds while the container is failing but not yet restarted, the pod may still receive requests. Readiness is the tool that stops traffic. Use both, each for its own purpose.
7Usage Patterns You Will Meet
Most real-world liveness probes fall into a small set of patterns. Learn to recognise them and you can design a good probe for almost any program.
A simple health endpoint
The most common pattern. The application offers a tiny web address that returns “OK” whenever the program’s own machinery is working. The kubelet calls it every few seconds. The endpoint should be quick and should not depend on other services, only on whether this program can still respond at all.
A TCP port check
For a database, a message broker or any program that does not speak web, the kubelet just tries to open its network port. It is very cheap and catches complete freezes, but it cannot tell whether the program behind the port is really working.
A command check
The kubelet runs a small command inside the container. It suits programs that expose no network check, for example by testing that a required file exists. It is flexible, but it starts a new process on every check, which costs more than a network check.
A heartbeat file
A clever way to detect a stuck background worker. The worker updates a small file every time it finishes a cycle. The liveness command checks that the file was updated recently. If the worker freezes, the file grows stale, the check fails, and the container restarts.
Startup probe plus liveness probe
For programs that take a long time to start, such as large Java applications loading big data sets, a startup probe gives a generous window to finish starting. Once it passes, the strict and quick liveness probe takes over. This avoids the old trick of a huge initial delay that also delayed detecting real problems.
Separate endpoints for liveness and readiness
A well-designed application offers two different health questions. “Am I alive?” only checks the program’s own core. “Am I ready?” also checks things like connections to a database. Each probe uses the matching endpoint, so a database outage stops traffic without causing pointless restarts.
A gRPC health service
Services built with gRPC can implement the standard health service, and the kubelet calls it directly. There is no need to add a separate web server just for health checks.
No liveness probe at all
For many programs, this is the right choice. If the program reliably exits when it breaks, the default restart behaviour is enough. A wrongly designed probe brings more risk than benefit. Add a liveness probe only when you know a silent-freeze failure can really happen.
The heartbeat file is like a factory worker who must press a button every few minutes. The supervisor does not need to watch the worker constantly. They only look at the time of the last button press. If it was too long ago, something is wrong.
Short-lived programs such as batch jobs often do not need liveness probes, because they run once and finish. A stuck job is usually better handled by a time limit for the whole job.
A worked scenario, told in words
Let us design a probe for a small service that converts uploaded pictures into thumbnails. It is a web service with a pool of worker threads. First we ask: how can it fail silently? The answer is that all worker threads might get stuck on a broken image, leaving none free. New uploads then wait forever, while the process remains alive.
Next we choose a check. A web endpoint that is served by the same worker pool would also get stuck, which is exactly what we want to detect. But it must be light: it returns a plain “OK” without touching storage or other services. We serve it on the normal port, so that a jammed worker pool makes it time out.
Then we choose numbers. The service starts in about eight seconds, so a startup probe with a thirty-second window is plenty. Normal answers take a few milliseconds, but occasional memory clean-ups pause it for up to two seconds. We set the timeout to four seconds, the period to ten, and the failure threshold to three. A real jam is therefore repaired in roughly forty seconds, and a two-second pause never causes trouble.
Finally, we test. In a test cluster we send the service an image built to jam its workers, watch the health check time out three times, and see the container restart. We also run a load test to confirm that busy but healthy containers are left alone. Only then do we roll the probe out to production.
8Security and Safety
A health check looks harmless, yet it is a doorway into your application and a lever that can restart it. Both deserve care.
Keep health endpoints private
A health address is meant for the kubelet, not for the world. Do not publish it through your public web entry point. If strangers can see it, they learn about your internals, and if it is heavy, they can use it to overload you.
Say little
A health answer should be a plain “OK” or a status code. Never include version numbers, database names, addresses or error details that would help an attacker.
No passwords in the probe
Probe settings are stored in the pod definition and are visible to anyone who can read the pod. Do not place tokens or passwords in custom headers or commands. Design the health endpoint so it needs none.
Careful with exec checks
A command probe runs inside your container, with its permissions. Keep the command tiny and fixed, never build it from outside input, and avoid tools that give the container extra power.
Allow the kubelet
Strict network policies must still let the kubelet reach the probe port on its own computer. Test this after any policy change, because a blocked probe looks exactly like a dead application.
HTTPS probes are not verified
The kubelet can probe over HTTPS but does not check the certificate. It confirms the program answers, not that the certificate is valid, so do not rely on the probe for certificate health.
The restart lever as a weakness
An attacker who can make your health check fail can force your containers to restart repeatedly. If the probe is expensive or depends on outside services, a flood of requests to it can cause exactly that. This is a form of denial of service. Simple, cheap, local health checks are naturally resistant.
Similarly, a probe that checks a shared dependency turns one outage into many. If ten thousand containers all restart because the database slowed down, the sudden burst of new connections can crush a database that was only struggling. Good design keeps such decisions out of the liveness path.
Imagine a fire alarm test button placed outside the building where anyone can press it. Pranksters would keep emptying the building. A health check exposed to the public, or wired to something fragile, is that button. It should be inside, out of reach, and connected only to what it is meant to guard.
A short security checklist
Health paths only on internal ports or routes. Answers with no sensitive detail. No secrets in probe settings. Cheap checks that cannot be triggered into heavy work. Network rules that allow the kubelet. And limited permission to edit pod definitions, since changing a probe can silently disable protection or cause restart storms.
Who may edit a deployment can also edit its probes. Loosening a probe can hide a real failure. Tightening it can cause outages. Treat probe changes like any other production change: review them and roll them out carefully.
9Choosing and Tuning Your Probe
Good probes are chosen with the application in mind. Here is how to decide, and how to find sensible numbers.
Which check method fits?
| Your program | Suggested check | Why |
|---|---|---|
| A web service or API | HTTP check on a light endpoint | Proves the request-handling machinery still responds |
| A gRPC service | gRPC health check | Uses the standard method already built for this |
| A database or broker with no web endpoint | TCP check, or a small command supplied by the product | Cheap, and catches complete freezes |
| A background worker with no port | Command check, often on a heartbeat file | Detects a stuck loop that no network check could see |
| A very slow starter | Startup probe plus a liveness probe | Generous start-up window, quick detection afterwards |
Finding the right numbers
There are no magic numbers, but there is a sound method. Start from what you can tolerate. How long can your service be broken before the damage matters? That gives an upper limit for period times threshold. Then look at how your program behaves under load. How long do its slowest normal responses take? How long is its worst pause when it cleans up memory? The timeout must be comfortably longer than those pauses.
Measure start-up time
Time how long the program needs from launch to first healthy answer, on a busy day and on a slow computer. This decides the startup probe window.
Measure the slowest normal pause
Check the longest delay a healthy program shows under peak load. Set the timeout well above it.
Choose the period
Ten seconds is a common choice. Shorter costs a little more work but finds failure sooner.
Choose the threshold
Three is the default. Raise it if brief stalls are normal, so that one bad moment does not kill a container.
Test the failure on purpose
In a test cluster, freeze the program deliberately and confirm the restart happens when and how you expect. Also load-test to confirm healthy containers are not restarted.
Tuning a probe is like setting a smoke detector’s sensitivity. Too sensitive and it screams every time you make toast. Too dull and it stays silent while the kitchen burns. You choose a setting that ignores toast and catches real fire, and you test it with a controlled bit of smoke.
Probes and cloud load balancers are different things
On Amazon EKS, an Application Load Balancer also performs health checks on its targets to decide where to send traffic. These are separate from Kubernetes probes. The load balancer’s check decides whether it sends web requests to a pod. The liveness probe decides whether Kubernetes restarts a container. It is wise to make them agree in spirit, but never assume one replaces the other. Readiness, not liveness, is the probe that ties in with traffic decisions during updates.
Write down, next to each probe, why each number was chosen. Six months later, when someone asks why the timeout is four seconds, the answer will be in the notes instead of lost.
10Advantages, Disadvantages and Trade-offs
No tool is perfect. A good engineer knows both what liveness probes give and what they cost.
Advantages
- Frozen programs are restarted automatically, with no human needed
- Recovery is fast, often within a minute
- Works with web, network, command and gRPC checks
- Runs locally on the computer, so it is quick and independent of the control centre
- Turns silent failures into visible events and counters
- Settings are simple and live in the pod definition
Disadvantages
- A badly tuned probe kills healthy containers
- A probe that checks dependencies can cause restart storms
- A restart hides the cause unless you collect logs and events
- A restart loses whatever is held only in memory
- It cannot fix a bug, only reset the symptom
- Adds another setting that must be maintained and tested
The trade-offs behind the lists
Quick detection versus false alarms. A short period and low threshold find failures quickly, but a healthy program that hiccups for a few seconds gets killed. A long period and high threshold are calm, but users suffer longer before recovery. The right balance depends on how costly a restart is versus how costly a freeze is for your service.
Shallow checks versus deep checks. A shallow check, such as “the web server answers”, rarely gives a false alarm but may miss subtle breakage. A deep check, such as “can I reach the database and the cache”, catches more but blames the wrong thing when a neighbour fails. For liveness, the safe rule is to stay shallow, and to leave deep checks to readiness and monitoring.
Restarting versus understanding. Automatic restarts hide problems. A memory leak that causes a restart every six hours may go unnoticed for months. Restarts should be counted, graphed and reviewed, not merely enjoyed.
One probe versus none. A pointless probe adds risk. If a program either works or exits, and has never been observed to hang, skipping the liveness probe is a legitimate choice.
Liveness probes compared with other recovery tools
A liveness probe is one layer in a stack of recovery tools, and it helps to see where it fits. The lowest layer is the automatic restart of a container that exits. The liveness probe extends this to containers that are stuck but not exited. Above that, a deployment notices when a whole pod disappears, for example because its computer failed, and creates a replacement on another computer. Above that, an autoscaler adds or removes pods as load changes. And above everything, monitoring and alerts tell humans about patterns the automation cannot fix.
Each layer handles a different size of problem. A liveness probe solves the small, local one: this one container is stuck. It cannot solve a broken release that fails everywhere, or a database that is down. Trying to make it do so is the source of most probe disasters.
11Monitoring, Logging and Failure Handling
Probes fix problems quietly. That is exactly why you must watch them, so the quiet fixes do not hide the loud causes.
Restart count
The most important number. A steady rise means something keeps failing. Cluster monitoring tools expose it for every container, and it should have an alert when it climbs quickly.
Probe failure events
The kubelet records each failure with its reason. Collect and store these events, because the cluster keeps them only for a short time.
Last termination reason
The container’s previous state shows why and how it stopped: an exit code, a signal, or a memory-limit kill. This separates probe kills from ordinary crashes.
Probe result counters
The kubelet publishes counts of probe successes and failures. Graphing them shows flapping, when a probe passes and fails in alternation, before it grows into a restart loop.
Logs from the previous container
After a restart, the log of the old container is the best clue to what went wrong. Ship logs to a central place, so they survive restarts.
Health endpoint response time
If the health check itself starts taking longer, trouble is approaching. Graph the time it takes to answer.
Failure scenarios worth rehearsing
The restart storm
A shared database slows down. Every liveness probe that checks it begins to fail, and all containers restart together. The burst of reconnections makes the database even slower, and the storm feeds itself. The cure is a probe that checks only the program itself, and separate readiness for dependencies.
Killed while still starting
A large program needs two minutes to start, but the liveness probe begins after ten seconds. It is killed again and again and never gets started. The cure is a startup probe with a generous window.
The memory-pause victim
A program periodically pauses for six seconds while cleaning up memory. A one-second timeout with a low threshold reads that as death. The cure is a longer timeout or more tolerance, or fixing the pause.
An overloaded computer
The whole computer is starved for processor time. Every probe on it slows down and fails, and healthy containers restart. Watch node-level pressure alongside restarts, and spread the work more evenly.
The invisible leak
A memory leak makes the program freeze every eight hours, and the liveness probe faithfully fixes it every time. Nobody notices until the leak worsens. Alert on restarts per day, and treat any repeating pattern as a bug to fix.
Restarts are like a car’s warning light being covered with tape. The car keeps running, but you have stopped hearing the message. Monitoring restarts uncovers the light so you can find the reason the engine complains.
Raise alerts for restarts climbing faster than usual, probes flapping, and pods stuck in CrashLoopBackOff. A single restart on a busy day is normal. A pattern is a story.
12Design Patterns and Anti-patterns
A pattern is a proven way of solving a common problem. An anti-pattern is a habit that looks sensible at first and causes pain later.
Patterns that work
Three probes, three jobs
Use startup for slow starts, readiness for traffic decisions, and liveness for stuck programs only. Never ask one probe to do all three jobs.
Shallow liveness, deeper readiness
Liveness checks only the program’s own machinery. Readiness may also check connections to other services. A dependency outage then stops traffic without causing restarts.
Dedicated health port
Serve health checks on a separate internal port with its own small pool of workers. A flood of customer traffic then cannot starve the health check.
Heartbeat for workers
Background workers update a timestamp each cycle. The probe checks that the timestamp is recent, catching a frozen loop.
Graceful shutdown
Make sure the program handles the termination signal and finishes its work, so a probe-triggered restart loses as little as possible.
Test the failure on purpose
Regularly freeze a test container and confirm the recovery works. A protection you have never tested is only a hope.
Anti-patterns to avoid
The habit
Making the liveness check connect to the database, the cache and every other service, “to be thorough”.
What goes wrong
When any of them has a bad moment, every container restarts, even though restarting cannot fix the neighbour. The storm of reconnections then makes the neighbour worse.
Better approach
Keep liveness local and shallow. Put dependency checks in readiness, where the effect is only to pause traffic.
The habit
Pointing both probes at the same endpoint with the same settings because it is easier.
What goes wrong
A condition that should only pause traffic, such as a busy moment, also triggers a restart. Small hiccups become outages.
Better approach
Use different endpoints, or at least different thresholds. Make liveness more patient than readiness.
The habit
Setting the initial delay to several minutes to give a slow program time to start.
What goes wrong
The delay applies to every start, including fast ones, and no liveness protection exists during it. A container that freezes early stays frozen for the whole delay.
Better approach
Use a startup probe. It waits only as long as needed and then hands over to a quick liveness probe.
The habit
Leaving the default one-second timeout for a busy program that sometimes pauses for longer.
What goes wrong
During peak load or a memory clean-up, healthy containers miss the deadline and are restarted at exactly the moment you need them most.
Better approach
Measure real pauses under load and set the timeout well above them, with a threshold that tolerates occasional slow answers.
The habit
A health endpoint that returns “OK” from a separate thread no matter what the rest of the program is doing.
What goes wrong
The probe passes while the real work is completely frozen. It gives a false sense of safety and protects nothing.
Better approach
Make the check exercise something real and lightweight, such as a heartbeat from the main work loop.
13Best Practices and Common Mistakes
These habits come from many teams running probes in production. Follow them and you will avoid most of the painful surprises.
Ask whether you need one
Add a liveness probe only if your program can freeze without exiting. Otherwise, rely on the default restart behaviour.
Keep it light and local
The check should be fast, cheap and independent of other services.
Add a startup probe for slow starters
Let it carry the long start-up window so the liveness probe can stay strict.
Set the timeout from real measurements
Base it on the slowest healthy pause under peak load, not on hope.
Be more patient than readiness
A restart is more disruptive than a traffic pause, so liveness should need more evidence before acting.
Watch restarts and events
Alert on rising restart counts and keep events and previous logs for investigation.
Test the failure and the recovery
Freeze a test container on purpose, and load-test to prove that healthy containers are left alone.
Common mistakes and their cures
| Mistake | What you see | Cure |
|---|---|---|
| Wrong port or path in the probe | Constant failures, restarts right after start-up | Check the address the application really serves |
| Probe begins before the program is ready | Restart loop that never gets going | Add a startup probe or a suitable initial delay |
| Timeout too short | Random restarts at peak load | Raise the timeout above real worst-case pauses |
| Probe checks external services | Everything restarts together during an outage | Move dependency checks to readiness |
| Endpoint requires login | Failures with an unauthorized answer | Make the health path open to the local kubelet, and only that |
| Program ignores the termination signal | Slow restarts and exit code 137 | Handle the signal for a graceful shutdown |
| Heavy health endpoint | The check itself slows the service | Return a simple answer with no database work |
| Nobody watches restart counts | A hidden leak or bug for months | Alert on restart rates and review them |
| Network policy blocks the kubelet | Healthy application fails its probe | Allow traffic from the node to the probe port |
Reviewing probes after every incident
Probes are not “set and forget”. Each incident is a chance to learn whether they helped or hurt. After any outage, ask three questions. Did a probe notice the problem sooner than a human would have? Did any probe make things worse by restarting healthy containers? And did the alerts on restart counts fire early enough to be useful?
Write the answers down and adjust the numbers. Over a few months, a team that does this ends up with probes that are boring, quiet and trusted, which is exactly what a safety net should be.
When containers restart unexpectedly, ask in this order: Is it a probe kill or a real crash? What does the probe failure message say? Is the address correct? Is the timeout realistic? Did anything else, such as a dependency or a busy computer, change at the same time? Following this order solves most cases in minutes.
14Real-World Usage Stories
Organisations of every size use liveness probes. The stories below are simplified illustrations of common situations, not descriptions of any one company’s private setup.
A large online marketplace
Think of a marketplace on the scale of Amazon or Flipkart. During a big sale one of the pricing service’s copies deadlocks after a rare timing bug. Its process stays alive, but it answers nothing. The liveness probe notices within thirty seconds and restarts it. Shoppers barely see a blip, and engineers read the restart alert the next morning and fix the bug.
A software-as-a-service company
A company running a large Java application learns that it needs ninety seconds to load its configuration. An early version killed it repeatedly during start-up. The team added a startup probe with a two-minute window and kept the liveness probe strict at ten-second intervals afterwards. Deployments became calm.
A message-processing service
A worker reads jobs from a queue and has no web port. It writes a timestamp to a small file each time it finishes a job. The liveness command checks that the timestamp is fresh. When the worker’s connection to the queue silently breaks, the timestamp goes stale, and the container restarts and reconnects.
A restart storm learned the hard way
A team made every liveness check call the shared database. One evening the database slowed for two minutes. Hundreds of containers restarted at once and opened fresh connections all together, which knocked the database over completely. After the incident, the team simplified the liveness probes and moved database checks into readiness.
A media platform
A video-processing service has occasional stuck encoding jobs. Instead of relying on the network, the team uses a heartbeat file updated by the encoder loop. Stuck jobs are detected and restarted, and the queue passes them to another worker.
A team that chose no probe
A small batch tool is written to exit at once on any error, and it runs for a few minutes at most. The team decided a liveness probe would add risk and no benefit, and set a total time limit for each run instead.
In every story the principle is the same: a liveness probe is a narrow safety net for one kind of failure, the silent freeze. Used narrowly and watched carefully, it saves nights of sleep. Used broadly, it creates outages.
15Frequently Asked Questions
16Summary and Key Takeaways
Key Takeaways
- Alive is not the same as running. A liveness probe catches the containers whose process exists but whose work is stuck for good.
- The kubelet runs the check and the restart follows. After enough failures in a row, the container, not the whole pod, is stopped and replaced.
- Choose the check that fits. Use an HTTP, TCP, command or gRPC check depending on what your program offers, and keep it light and local.
- Know the three probes. Startup protects slow starts, readiness controls traffic, and liveness triggers restarts. Do not ask one to do the others’ jobs.
- Tune from measurements. Period, timeout and threshold decide how fast a freeze is caught and how easily healthy programs are wrongly killed.
- Never check shared dependencies in liveness. It turns a single outage into a restart storm. Leave those checks to readiness and monitoring.
- Watch the restarts. Restarts fix symptoms, not causes. Alert on restart counts, keep events and previous logs, and test the failure on purpose.