CodeBlanks Logo Icon CodeBlanks

Health check

Learn to write a /healthz health endpoint.

Health checks

Orchestrators ask two questions: liveness — is the process alive? (restart it if not) and readiness — is it ready for traffic? (is the database connected, is warm-up done?).

mux.HandleFunc("GET /livez", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("ok"))
})
mux.HandleFunc("GET /readyz", func(w http.ResponseWriter, r *http.Request) {
    if err := db.PingContext(r.Context()); err != nil {
        http.Error(w, "db yok", http.StatusServiceUnavailable)
        return
    }
    w.Write([]byte("ok"))
})

Not ready while shutting down

During graceful shutdown the service first flips readiness to "not ready", waits for the load balancer to stop sending traffic, then finishes in-flight requests and exits. An atomic flag is enough for this:

var hazir atomic.Bool
hazir.Store(true)

// on SIGTERM
hazir.Store(false)
time.Sleep(5 * time.Second)
srv.Shutdown(ctx)

Practice Readiness endpoint

Declare var hazir atomic.Bool. The /readyz handler returns 503 if the flag is false and 200 if true. Send two requests — with the flag false and after setting it true — and print both codes on one line.

Starter code

main.go
package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
    "sync/atomic"
)

func main() {
    // buraya yaz
}

Sample solution

main.go
package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
    "sync/atomic"
)

var hazir atomic.Bool

func readyz(w http.ResponseWriter, r *http.Request) {
    if !hazir.Load() {
        http.Error(w, "hazır değil", http.StatusServiceUnavailable)
        return
    }
    w.Write([]byte("ok"))
}

func istek() int {
    rec := httptest.NewRecorder()
    readyz(rec, httptest.NewRequest("GET", "/readyz", nil))
    return rec.Code
}

func main() {
    once := istek()
    hazir.Store(true)
    fmt.Println(once, istek())
}

Expected output

503 200

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What can happen if the liveness check also checks the database?

  • The application speeds up
  • A brief database outage restarts every pod for nothing Correct answer
  • It becomes safer
  • Nothing changes

Explanation: Restarting doesn't fix a database problem; dependency checks go in readiness, liveness looks at the process itself.

2 Unavailable code

Question
http.Error(w, "hazır değil", http.____)
Answer
http.Error(w, "hazır değil", http.StatusServiceUnavailable)

Explanation: 503 Service Unavailable reports that the service isn't ready for traffic right now.

3 Check and question

Term Meaning
/livez Is the process alive?
/readyz Can it take traffic?
503 Not ready
atomic.Bool Safe ready flag

All lessons in Advanced