Home » Readiness, Liveness, and Startup Probes: Choosing the Right Check

Readiness, Liveness, and Startup Probes: Choosing the Right Check

0 comments
A sprouting seed, a leafy upright plant and a wilted plant appear in three separate soil sections with exposed roots.

Use readiness to decide whether an instance should receive new service traffic, liveness to identify a local failure that justifies restarting its container, and startup to allow initialization before the other checks begin. Choose the recovery action first, then design the condition that should trigger it.

A dependency outage is a useful test of this distinction. Restarting every application instance will not repair an unavailable database, and can add reconnection pressure just when that database is struggling.

Give each probe a specific question

Kubernetes documents three probe roles: a configured startup probe gates readiness and liveness until it succeeds; failed readiness makes a container unready; failed startup or liveness beyond the configured threshold can cause the container to be killed, with subsequent behavior governed by its restart policy. See the probe concepts.

For a synthetic catalog API, assign narrower application meanings:

Application state Startup condition Liveness condition Readiness condition Intended response
Loading required local catalog Not finished Not evaluated by Kubernetes yet Not evaluated yet Wait within startup budget
Serving normally Finished Processing can progress Can serve the defined traffic Admit traffic
Required database unavailable Finished Local processing still works Required operation cannot succeed Stop new traffic; retain process
Worker loop irrecoverably stalled Finished Cannot make required progress Cannot serve Restart after tolerance
Draining for shutdown Finished Local processing still works Not accepting new operations Stop admission; finish accepted work

The “database unavailable” row assumes every request covered by this Service requires the database. If the service can answer useful cached reads, taking the whole instance out of traffic may be the wrong policy. State the service contract before treating any dependency as a universal readiness requirement.

Likewise, “stalled” requires evidence. A separate health thread returning 200 can remain responsive while the worker pool is permanently blocked. A progress check needs a signal connected to the work that matters, without mistaking an idle service for a failed one.

Design the endpoint before tuning the interval

In the proposed API, /health/startup reports completion of required initialization. /health/live reports local progress. /health/ready reports initialized, capable, and accepting work. These paths are application choices, not built-in Kubernetes endpoints.

Keep their responses small and bounded. A health check that walks every dependency can become slower than the request path it supervises. An endpoint should not disclose connection strings, internal exception dumps, or customer records. Detailed diagnostic evidence belongs in appropriately controlled telemetry.

If readiness needs database information, decide how it obtains that information and how stale it may be. Reusing a bounded connection-state signal avoids issuing an expensive query on every probe, but can delay detection. A lightweight direct check gives fresher evidence and adds load. Evaluate the tradeoff with the actual pool, timeout, and request volume; neither choice is universally correct.

Liveness deserves a stricter question: what failure does a restart repair? If the process exits reliably on unrecoverable failure, a separate liveness probe may add little. If it can deadlock while remaining alive, a representative progress check can be useful. A probe that fails mainly under ordinary load can turn a capacity problem into repeated loss of warmed instances.

A manifest fragment with explicit assumptions

This illustrative fragment assumes the application implements the three endpoints on port 8080:

spec:
  terminationGracePeriodSeconds: 30
  containers:
    - name: catalog
      # image is supplied by the deployment's reviewed artifact policy
      ports:
        - name: http
          containerPort: 8080
      startupProbe:
        httpGet: {path: /health/startup, port: http}
        periodSeconds: 2
        timeoutSeconds: 1
        failureThreshold: 30
      readinessProbe:
        httpGet: {path: /health/ready, port: http}
        periodSeconds: 5
        timeoutSeconds: 1
        failureThreshold: 2
      livenessProbe:
        httpGet: {path: /health/live, port: http}
        periodSeconds: 10
        timeoutSeconds: 1
        failureThreshold: 3

The startup values express a nominal budget of about 60 seconds. They are synthetic inputs, not a measured startup requirement or an exact scheduling guarantee. A one-second timeout is appropriate only if the endpoint can reliably respond within it under the workload you intend to support. The configuration guide explains the timing and threshold fields; validate the complete manifest against your cluster version.

The fragment was not deployed or validated by a Kubernetes API server. Its missing image is deliberate: it illustrates probe configuration rather than providing a runnable workload with an invented artifact.

What a local policy test can establish

We executed a pure Python 3.14.2 fixture for the catalog API's proposed health policy:

def checks(initialized, progress, database, stopping):
    return {
        "startup": initialized,
        "live": progress,
        "ready": initialized and progress and database and not stopping,
    }

Five state assertions passed: starting, serving, database unavailable, stalled, and draining. The database failure left live true and made ready false. Draining did the same. A failed progress condition made both false.

The function returns all three values so the policy can be inspected. It does not simulate Kubernetes suppressing readiness and liveness during startup. It also does not test HTTP status mapping, threshold timing, restart behavior, routing convergence, or whether progress and database accurately reflect a real process. Those are the next integration checks, not conclusions from five booleans.

The most valuable service test would induce the relevant failure in a controlled environment and observe both the probe and the recovery action. A temporary dependency failure should not create a restart loop under this policy. A deliberately stalled worker should become detectable even if an unrelated management thread remains responsive.

Observe consequences, not only green endpoints

Track transitions alongside request outcomes and container restarts. A service whose readiness repeatedly flaps may be moving traffic among too few instances. A probe that always passes can be equally misleading if user requests fail through a different path.

Correlate a transition with the instance, deployment revision, and failure reason using bounded labels. Our guide to logs, metrics, and traces explains how to connect aggregate impact to specific events. Avoid logging secrets or full dependency responses merely to explain a failed check.

Review the probe whenever initialization, worker concurrency, dependency requirements, or shutdown behavior changes. Its purpose is to select a useful action for a recognizable state. An endpoint that answers “the process exists” cannot by itself justify “this instance can serve the next request.”

Primary Kubernetes documentation was consulted October 28, 2026. Only the local application-policy fixture was executed; no cluster behavior was tested.

You may also like