Skip to content
Blog

Kubernetes Liveness, Readiness, and Startup Probes Explained

The three probe types keep Kubernetes applications healthy — and misconfigure one and you'll restart healthy containers or starve them of traffic. Here's how each works.

Published on • October 11, 2026

AI Assistant

Kubernetes can restart a crashed container trivially. The hard problem is knowing whether a container is running but broken — hung on a deadlock, overloaded, or still warming up. Probes are how the kubelet asks your application “are you okay?” — and there are three kinds, each with a distinct job. Get them confused and you’ll either restart healthy pods or send traffic to broken ones.

The three questions

Every container lifecycle raises three separate questions:

  1. Is it alive? → liveness probe. Should Kubernetes restart a container that’s wedged?
  2. Is it ready for traffic? → readiness probe. Should this pod be in the Service’s endpoint list right now?
  3. Is it done starting up? → startup probe. Can slow-starting apps boot without being killed prematurely?

They’re configured independently and don’t depend on each other to succeed.

Liveness probes: “should I restart you?”

The liveness probe detects states a process can’t recover from — deadlocks, corrupted state. When it fails, the kubelet kills the container and the pod’s restartPolicy takes over.

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 3
  periodSeconds: 3

Four probe mechanisms are supported:

  • httpGet — success is any 2xx/3xx status code (anything else fails).
  • exec — run a command in the container; exit code 0 succeeds. Simple and universal: cat /tmp/healthy.
  • tcpSocket — open a TCP connection to the port; connect succeeds = healthy. Coarse but protocol-agnostic.
  • grpc — call the gRPC Health Checking Protocol, stable since Kubernetes v1.27.

The classic example from the Kubernetes probe task docs: a container creates /tmp/healthy, deletes it after 30 seconds, and the liveness probe — cat /tmp/healthy every 5 seconds — kills and restarts it once the file is gone.

The liveness anti-pattern: pointing liveness at something that depends on external services (a database, a downstream API). If the database blips, you restart every app pod — a self-inflicted outage cascading through your system. Liveness should check only internal, self-contained state.

Readiness probes: “should I receive traffic?”

A pod that fails its readiness probe is removed from the Service’s endpoints. It keeps running — no restart — it just gets no user traffic until it recovers.

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10
  failureThreshold: 3

Readiness is where your app answers operational questions: Has it loaded its configuration? Is a warmup cache complete? Is it safe to take writes?

Two subtleties:

  • Readiness runs for the pod’s whole life, not just at startup. A dependency outage should flip readiness to false so the Service stops routing to an instance that’s about to fail requests.
  • Readiness failing doesn’t restart anything. If your app can only recover by being restarted, that’s a liveness concern — use both probes on the same container for both behaviors.

Readiness is also the correct probe for graceful shutdown: when a pod is deleted, Kubernetes removes it from endpoints first (via the terminating state), so don’t fight it with clever signal handling alone.

Startup probes: “give me time to boot”

Slow applications — JVM apps, large ML model servers — can’t pass a liveness probe quickly. Without protection, a tight liveness probe kills them during startup, and they crash-loop forever.

The startup probe runs until it succeeds once, and only then do liveness and readiness take over:

startupProbe:
  httpGet:
    path: /healthz
    port: 8080
  failureThreshold: 30
  periodSeconds: 10

Here the app gets 30 × 10 = 300 seconds (5 minutes) to finish booting. If it never succeeds, the container is killed and subject to restartPolicy. Once it passes, the liveness probe (say, failureThreshold: 1, periodSeconds: 10) resumes its job of fast deadlock detection.

Rule of thumb: if your app might take more than ~30 seconds to start, use a startup probe instead of inflating initialDelaySeconds — delays don’t adapt, and a large delay also delays your deadlock detection.

Shared configuration fields

All three probes use the same timing knobs:

FieldPurposeDefault
initialDelaySecondsWait before first probe0
periodSecondsInterval between probes10
timeoutSecondsPer-probe timeout1
successThresholdConsecutive successes to pass1 (readiness: 1)
failureThresholdConsecutive failures to fail3

For HTTP probes you can reference a named port (port: liveness-port), and HTTP/2 cleartext (h2c) probing is available behind a feature gate for gRPC-only services.

A complete example

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: api
        image: my-api:2.1.0
        ports:
        - containerPort: 8080
        startupProbe:
          httpGet: { path: /healthz, port: 8080 }
          failureThreshold: 30
          periodSeconds: 10
        livenessProbe:
          httpGet: { path: /healthz, port: 8080 }
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet: { path: /ready, port: 8080 }
          periodSeconds: 5
          failureThreshold: 2

Debugging probes

When a probe misbehaves, kubectl describe pod shows the events:

kubectl describe pod my-api-7d9f | tail -20
# Warning  Unhealthy  Liveness probe failed: HTTP probe failed with statuscode: 500
# Normal   Killing    Container my-api failed liveness probe, will be restarted

A restart loop with Unhealthy events almost always means a liveness probe that’s too aggressive or pointed at the wrong dependency.

The decision tree

  • App might hang after startup? → liveness
  • App has dependencies that should gate traffic? → readiness
  • App takes ages to boot? → startup (then liveness takes over)
  • Never: liveness on an external dependency; readiness that never recovers without a restart.

Get the trio right and Kubernetes does the right thing automatically — restart what’s broken, shield what’s unready, and wait for what’s slow. The full reference lives in the Kubernetes probe documentation.