Ignition

Health Check

Learn how health-check endpoints report application availability, support load balancers and orchestrators, and differ from liveness, readiness, and startup probes.

A health check is a request used to determine whether an application or service is healthy enough for a particular operational purpose. A well-designed check gives infrastructure a lightweight, machine-readable signal about whether an instance is reachable and functioning at a basic level.

Health checks are not a replacement for detailed diagnostics, application monitoring, or observability dashboards. They answer a focused question, such as “Can this instance receive traffic?” Detailed logs, metrics, traces, and dashboards are better suited to explaining why an application is unhealthy.

Why health checks matter

Infrastructure can use health-check results to make automated decisions without interpreting human-oriented pages or log messages. Common consumers include:

  • Load balancers: stop routing requests to instances that fail their checks.
  • Container orchestrators: restart processes that are no longer alive or remove unready instances from service routing.
  • Uptime monitors: report availability incidents when an endpoint repeatedly fails.
  • Deployment systems: validate that a new release is serving traffic before continuing or completing a rollout.

A health check should therefore be predictable, fast, and easy for automated clients to evaluate.

Endpoint behavior

Path and method

Expose a dedicated path for the check rather than relying on a complex business operation. A common design is a GET request to a path such as /health, /healthz, or an application-specific health path. The exact path is a deployment contract: the application and the load balancer, orchestrator, or monitor must use the same path.

When infrastructure calls the endpoint, it should not need a browser session, application cookie, or interactive login. If access must be restricted, use network controls or an infrastructure-compatible authentication method that the legitimate checker supports.

Status codes and response bodies

An HTTP status code is the response code that lets a client classify the result. Return a successful status, commonly 200 OK, when the instance satisfies the purpose of that check. Return a non-success status when it should not be considered available for that purpose. The exact non-success code depends on the contract; a common choice is 503 Service Unavailable for an instance that is temporarily unable to serve traffic.

The response body should be short and machine-readable. For example:

HTTP/1.1 200 OK
Content-Type: application/json

{"status":"ok"}

A failure visible to public infrastructure can remain generic:

HTTP/1.1 503 Service Unavailable
Content-Type: application/json

{"status":"unhealthy"}

Set an appropriate content type, such as application/json for JSON. Do not put passwords, access tokens, stack traces, database connection strings, internal hostnames, or detailed dependency errors in the response.

Predictable and fast execution

  • Keep the endpoint unauthenticated when it is intended for infrastructure that cannot perform user authentication.
  • Make the normal path complete quickly and consistently.
  • Avoid rendering large pages, performing expensive calculations, or invoking optional application features.
  • Keep the check independent of nonessential routes and background features.
  • Make failures observable through protected logs and metrics without turning every probe into a noisy alert.

Types of health checks

Different checks answer different operational questions. Confusing them can cause unnecessary restarts or route traffic to an instance that is not ready.

Check type | Question answered | Typical action on failure | Dependency depth

Liveness probe | Is the process still running and able to make progress? | Restart the process or container. | Usually process-level and shallow.

Readiness probe | Can this instance safely receive new traffic? | Remove the instance from routing. | May include required dependencies.

Startup probe | Has initialization had enough time to complete? | Delay liveness and readiness decisions during startup. | Initialization-focused.

Liveness checks

A liveness probe determines whether a process should continue running or be restarted. A simple process-level check is often sufficient: the application can accept the request and report that its main event loop or server process is responsive.

Liveness should not normally depend on every database, queue, cache, or external API. If an optional dependency is unavailable, restarting the whole process may not fix the problem. A dependency-heavy liveness check can create a restart loop during an outage.

Readiness checks

A readiness probe determines whether an instance can safely receive traffic. Readiness may check required dependencies such as a database, message queue, cache, or essential external service when the application cannot correctly handle requests without them.

For example, an application can remain running while its database is unavailable. Its liveness check can still succeed, but its readiness check can return a non-success status. A load balancer then stops sending new traffic to that instance while the process remains available for recovery and diagnosis.

Dependency checks should be bounded and purposeful. Do not perform destructive operations, broad data scans, large queries, message publishing, or expensive external workflows from a health endpoint. Prefer a low-cost connectivity or capability test with a strict timeout, and consider caching dependency state when probe frequency is high.

Startup checks

A startup probe gives an application additional initialization time before liveness or readiness failures are acted upon. This is useful for applications that load configuration, warm caches, run migrations, compile assets, or establish required connections during startup.

For example, a platform can use a startup check while the application initializes. Once startup succeeds, normal liveness and readiness checks take over. This prevents a slow but healthy startup from being mistaken for a crashed process.

Response design guidelines

Condition | Suggested status class | Response detail level | Operational consequence

Process is responsive and ready | 2xx | Minimal success payload | Route traffic or mark the instance available.

Process is running but a required dependency prevents service | 503 | Generic unhealthy or not-ready state | Stop routing traffic; do not necessarily restart.

Process cannot respond within the timeout | Timeout or non-success result | No diagnostic details to the caller | Treat the check as failed and investigate latency.

Endpoint path or method is misconfigured | 404 or 405 | Minimal error response | Correct the infrastructure or application configuration.

The status and body should be stable enough for automation. Detailed reasons belong in protected logs, metrics, traces, or an internal diagnostics system rather than in a public response.

Manual verification

Use a command-line HTTP client to verify the route from a location that has the same network access as the infrastructure checker. The timeout prevents a command from waiting indefinitely.

curl --fail --silent --show-error --max-time 2 \
  --request GET https://example.invalid/health

The example expects a successful HTTP response such as 200 OK and a short body such as {"status":"ok"}. Replace the example host with the real service address in your environment. Also test from the load balancer or orchestrator network, because a request from a developer workstation may not reveal firewall, routing, DNS, port, or TLS problems.

Infrastructure configuration

Probe settings should reflect the endpoint's purpose and normal response time. The following generic configuration illustrates separate liveness and readiness behavior:

liveness:
  path: /health/live
  method: GET
  interval: 10s
  timeout: 2s
  retries: 2
  failure_threshold: 3

readiness:
  path: /health/ready
  method: GET
  interval: 5s
  timeout: 2s
  retries: 2
  failure_threshold: 2
  • Interval: time between checks. A shorter interval detects changes sooner but creates more traffic.
  • Timeout: maximum time allowed for one response. It should exceed normal endpoint latency but remain short enough to detect a stuck instance.
  • Retries: additional attempts before treating an individual result as a failure. Retries can reduce reactions to brief network errors.
  • Failure threshold: number of consecutive failures required before an action is taken. A higher threshold reduces sensitivity to transient faults.

Use a startup probe when initialization is slow:

startup:
  path: /health/startup
  method: GET
  interval: 5s
  timeout: 2s
  failure_threshold: 24

Probe timing should be tested under normal load and during controlled dependency failures. Avoid making all instances perform expensive checks at the same instant, and keep response generation cheap enough that health traffic does not compete with user requests. Where appropriate, use a separate listener, lightweight in-process state, or carefully bounded dependency checks.

Operational effects

  • Traffic routing: a failed readiness result can remove an instance from a load balancer's target set.
  • Restart behavior: a failed liveness result can cause an orchestrator to restart a process.
  • Alerting: repeated failures across the service can trigger availability alerts; a single transient failure may only be recorded.
  • Deployment validation: a release can be held, rolled back, or marked successful based on health results from new instances.

Health results should be correlated with application logs, resource metrics, dependency metrics, and deployment events. A probe says that an operational condition exists; surrounding telemetry helps explain its cause.

Security and reliability

  • Return only the minimum information needed by the caller.
  • Never expose secrets, stack traces, internal topology, credentials, or detailed dependency failures in public responses.
  • Keep the endpoint independent of nonessential application features and avoid circular dependencies.
  • Apply rate limiting or network restrictions only if they remain compatible with every legitimate load balancer, orchestrator, monitor, and deployment system.
  • Record useful failure context in protected logs or internal telemetry, including the check type, instance, latency, and failure category.
  • Aggregate or suppress repeated identical probe failures so normal polling does not produce alert noise.

Troubleshooting

The check fails while the application appears to be running

  • Check application logs for initialization or dependency errors.
  • Verify that the endpoint route is registered and reachable on the expected port.
  • Confirm that required services are available and that credentials and network access are valid.

Correct the failing dependency or endpoint configuration, then verify that the response returns within the configured timeout.

Instances are repeatedly restarted

  • Determine whether liveness is incorrectly testing an optional or temporarily unavailable dependency.
  • Review probe timing during startup.
  • Check whether endpoint response time exceeds the configured timeout.

Keep liveness lightweight, move dependency validation to readiness where appropriate, and tune startup timing for the application's real initialization period.

Healthy instances receive no traffic

  • Inspect readiness status codes and the load balancer's health state.
  • Confirm network access from the balancer or orchestrator to the endpoint.
  • Check the path, port, host header, TLS settings, and authentication assumptions.

Align infrastructure probe settings with the deployed endpoint and remove access barriers that prevent legitimate health-check requests.

The endpoint leaks implementation details

  • Review response bodies and error handling when dependencies fail.
  • Check whether debugging output is enabled.

Return a minimal public status response and place detailed diagnostic information in protected logs or internal telemetry.

Exam-relevant notes

  • A health check is a focused availability signal, not a complete monitoring dashboard.
  • Liveness asks whether to restart; readiness asks whether to route traffic; startup asks whether initialization has completed.
  • A database failure commonly makes readiness fail, but should not automatically make liveness fail.
  • Use HTTP status codes consistently: success for an acceptable state and a non-success response for an unacceptable state.
  • Health endpoints should be fast, predictable, minimal, and safe to call repeatedly.
  • Do not expose sensitive diagnostics in public health responses.

For related deployment and monitoring concepts, continue with Health Check.