Health Check Endpoint
Fast recall
Quick revision
Core answer
Whether you understand Health Check Endpoint beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
The implementation:
func healthHandler(w http.ResponseWriter, r *http.Request) {
// Liveness: the process is up — 200 always (unless crashing)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
// The deep version — checks dependencies:
func readinessHandler(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if err := db.PingContext(r.Context()); err != nil {
// The DB is down — I'm running but can't serve
w.WriteHeader(http.StatusServiceUnavailable)
json.NewEncoder(w).Encode(map[string]string{"status": "unhealthy"})
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "ready"})
}
}
mux.HandleFunc("/healthz", healthHandler) // liveness
mux.HandleFunc("/readyz", readinessHandler(db)) // readinessThe two types (the Kubernetes semantics — the industry vocabulary):
- LIVENESS (/healthz): 'is the process alive?' — 200 while running. If it fails, the orchestrator RESTARTS the container (the process is wedged).
- READINESS (/readyz): 'can I serve traffic?' — 200 when dependencies (DB, downstream) are reachable. If it fails, the load balancer STOPS ROUTING to me (but doesn't restart).
The distinction's purpose: a DB outage with a failing readiness (routes stop, service removed from LB, no restarts — DB recovers, routes return). If readiness were liveness, every DB blip would RESTART every pod — the cascade.
The instrumentation rules: the health check is the ONE endpoint that must never touch the DB (the liveness version) — a DB-connected liveness is the self-inflicted outage. The readiness CAN check dependencies (that's its job) — with a timeout (the dependency check must not hang).
Health Check Endpoint
Direct Answer
GET /healthz or /health returning 200 with a JSON body (or just 200) — checked by the load balancer/orchestrator (Kubernetes probes, Docker healthcheck). Liveness (am I running) vs readiness (can I serve).
Deep Dive & Architecture
The kubelet probe mechanics (the Kubernetes side): the livenessProbe and readinessProbe in the pod spec — the kubelet polls the endpoint on the interval; failures count against the failureThreshold; crossing it triggers the action (restart for liveness, remove from service for readiness). The initial delay (the startup grace) and the timeout (the probe's own deadline) are the tuning.
The anti-patterns the question tests for: (1) the liveness probe that checks the DB (restarts cascade); (2) the readiness with no dependency check (routes traffic to a pod that can't serve — the check that's always 200 is a decorative readiness); (3) the health endpoint that allocates or logs on every request (the probe traffic is constant — the endpoint is the hottest route).
The Go-specific pattern: the health mux mount WITHOUT middleware (auth on the health path = the probe gets a 401 = the loop). The dedicated listener (a second port for health/monitoring — the admin port) isolates health from the main service's middleware stack.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Health Check Endpoint in a real project?
- How would you compare Health Check Endpoint with an alternative?
- What is a common mistake when using Health Check Endpoint?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.