Health Checks
AISIX exposes separate health and status endpoints for process, traffic, configuration, and model state. The same endpoints apply to the open-source AISIX gateway and to AISIX gateways connected to AISIX Cloud. Use the endpoint that matches the condition you want to monitor. To verify the complete caller-to-provider path, send a test request through the gateway.
| Question | Endpoint | Listener |
|---|---|---|
| Is the process running and not shutting down? | GET /livez | Proxy |
| Should this instance receive proxy traffic? | GET /readyz | Proxy |
| Has this instance applied any valid configuration? | GET /status/ready | Metrics/status |
| What configuration is this instance serving? | GET /status/config | Metrics/status |
| Is a model available for routing? | GET /status/models | Metrics/status |
These endpoints do not require authentication. The metrics/status endpoints are available when Prometheus metrics are enabled, as they are by default. Keep that listener private to monitoring and operations systems.
Proxy Liveness
Use /livez for process liveness:
curl -i "http://127.0.0.1:3000/livez"
A healthy process returns 200 OK with an ok body. During graceful shutdown, liveness returns 503 Service Unavailable so orchestration and traffic systems can replace or remove the instance.
Append ?verbose=1 when investigating manually. Do not make an automated probe depend on the verbose response body.
Liveness is intentionally narrow. It does not prove that the gateway has loaded configuration, that a model is available, or that a provider request can succeed.
Traffic Readiness
Use /readyz to decide whether an instance should receive traffic:
curl -i "http://127.0.0.1:3000/readyz"
It returns 503 Service Unavailable while the instance is draining or before it applies its first configuration. After a valid configuration is available, the gateway remains ready for as long as it can serve that configuration.
A control-plane or configuration-store interruption does not make a running gateway unready merely because no recent update arrived. A stalled source commonly affects every instance, so withdrawing them would remove the traffic path rather than shift traffic to a healthy peer. Monitor configuration freshness separately.
Append ?verbose=1 when investigating why an instance is not ready. Do not make an automated probe depend on the verbose response body.
For Kubernetes, point the liveness and readiness probes at /livez and /readyz on the proxy listener. Give the gateway enough termination time to drain in-flight and streaming requests.
Shutdown and Draining
A load balancer learns that an instance is withdrawing on its next health check, not the moment the instance decides to. Between those two points it keeps routing new connections. Closing the listener as soon as the shutdown signal arrives would refuse every connection routed inside that interval. Callers then see gateway errors during an ordinary rolling update or scale-down.
So the gateway separates the two events. On SIGTERM or SIGINT it:
- Answers
/readyzand/livezwith503 Service Unavailableimmediately, so the next health check withdraws it. - Keeps accepting new connections for at least
shutdown.min_drain_secs, which defaults to 30 seconds. - Adds
Connection: closeto every HTTP/1.1 response, so a client that pools connections retires them as it uses them instead of holding idle ones open. HTTP/2 clients receive aGOAWAYframe when the listener closes. - Stops accepting only after that window has elapsed and nothing is left in flight.
- Finishes the remaining in-flight requests with no deadline of its own, then exits.
Set min_drain_secs above the detection latency of whatever load-balances the instance. A Kubernetes readiness probe needs periodSeconds x failureThreshold. An external load balancer needs its own check interval multiplied by its retry count. Setting it too low closes the listener while traffic is still arriving. Setting it too high only delays the exit.
shutdown:
min_drain_secs: 30
The window is a minimum, not a deadline. After it elapses the gateway still waits for the in-flight count to reach zero, so a load balancer slower than configured cannot make it close under live traffic. 0 drops the window entirely and is only correct when nothing routes to the instance by health check.
Because the in-flight drain is unbounded, the deployment platform sets the real limit on the whole sequence: terminationGracePeriodSeconds in Kubernetes, TimeoutStopSec under systemd. Size it above your longest request. A preStop hook counts against the Kubernetes budget too, and an inference call or a streaming response can run for minutes.
Point the health check of an external load balancer at /readyz rather than at a bare TCP connect. A TCP check cannot observe readiness, so the only signal it ever receives is the listener closing — the very event the drain window exists to avoid.
Configuration State
The metrics/status listener provides two configuration checks.
GET /status/ready is a configuration-only startup gate:
503 Service Unavailablebefore the first valid configuration is applied;200 OKafter a valid configuration is available, including while AISIX serves a last-known-good snapshot after a later update fails.
GET /status/config explains what AISIX observed and applied:
curl -sS "http://127.0.0.1:9090/status/config"
Use it when a resource update does not appear in proxy behavior. Compare the source and applied state, then inspect rejected resources and the latest load failure. See Configuration Status for the complete response fields, state meanings, Prometheus metrics, and alert examples.
Configuration status does not replace caller-facing verification. After the expected snapshot applies, query GET /v1/models and send the request whose behavior changed. See Configuration Propagation.
Per-Model Runtime Health
Use GET /status/models when the gateway is ready but routing avoids a model or reports no eligible target:
curl -sS "http://127.0.0.1:9090/status/models"
Each configured model reports one of these high-level states:
healthy: available for routing;cooldown: temporarily removed after recent upstream failures;unhealthy: excluded after failed background model checks;not_applicable: a virtual model whose availability derives from its targets.
The status view helps identify cooldown and background-check failures, but it does not validate caller access or provider credentials. A model can report healthy while a caller API key, provider key, or upstream response still prevents a request from succeeding.
See Configuration Status for the full response fields.
Combined Health Signals
Work from the earliest failing layer:
| Signal | Next Check |
|---|---|
/livez fails. | Process state, listener binding, listener TLS, and shutdown state |
/readyz fails. | Drain state and initial configuration availability |
/status/ready fails. | Initial configuration source and load errors |
/status/config is degraded or out_of_sync. | Rejected resources, source connectivity, and last_failure |
/status/models reports cooldown or unhealthy. | Provider credential, provider availability, model checks, and outbound network |
| Every health endpoint succeeds but the request fails. | Caller access, provider path, policy enforcement, and upstream response |
Finish with the same path the application uses:
AISIX_API_KEY="YOUR_CALLER_API_KEY"
curl -sS "http://127.0.0.1:3000/v1/models" \
-H "Authorization: Bearer ${AISIX_API_KEY}"
Then send a real request through the required endpoint and model. That final probe verifies conditions that runtime health endpoints deliberately do not evaluate.
Next Steps
Use Troubleshooting to narrow a failed health or request-path check to configuration, caller policy, AISIX Cloud projection, or the upstream provider.