Health Checks and Production Tuning
HEALTHCHECK, tini, signal handling in containers
Health Checks and Production Tuning is a free Go Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Health check endpoints
A health check endpoint lets load balancers and orchestrators verify the service is alive and ready to serve traffic. Two common kinds: liveness (is it running?) and readiness (can it serve requests?).
Liveness endpoint
Returns 200 OK if the process is alive. A simple always-passing handler — the process being up is sufficient:
mux.HandleFunc("/healthz/live", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})Readiness endpoint
Returns 200 only when the service is ready (DB connected, cache warmed up, migrations done). Returns 503 during startup or degraded state:
mux.HandleFunc("/healthz/ready", func(w http.ResponseWriter, r *http.Request) {
if err := db.PingContext(r.Context()); err != nil {
w.WriteHeader(http.StatusServiceUnavailable); return
}
w.WriteHeader(http.StatusOK)
})Kubernetes probes
Configure liveness and readiness probes in your Kubernetes Deployment spec:
livenessProbe:
httpGet: { path: /healthz/live, port: 8080 }
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet: { path: /healthz/ready, port: 8080 }
initialDelaySeconds: 3
periodSeconds: 5GOMAXPROCS tuning
In containers, GOMAXPROCS defaults to the host CPU count, not the container's CPU limit. Use go.uber.org/automaxprocs to set it correctly from cgroup limits.
import _ "go.uber.org/automaxprocs"Memory limits
Set GOMEMLIMIT (Go 1.19+) to the container memory limit to allow the GC to use memory more aggressively before the OOM killer triggers:
import "runtime/debug"
debug.SetMemoryLimit(512 * 1024 * 1024) // 512 MiBGC tuning
Set GOGC to control GC frequency. Default is 100 (GC when heap doubles). Lower values reduce memory at the cost of more frequent GC; higher values trade more memory for less GC.
os.Setenv("GOGC", "200") // allow heap to grow 2× before GCConnection pool tuning
Set database connection pool limits appropriate to your container's resource limits and the database's max_connections:
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(10)
db.SetConnMaxLifetime(5 * time.Minute)Metrics exposure
Expose Prometheus metrics on a separate port (not the main API port) to avoid leaking internal data to external clients:
go func() {
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":9090", nil)
}()Graceful shutdown in Kubernetes
Set terminationGracePeriodSeconds in the pod spec to allow enough time for the shutdown timeout. Return 503 from the readiness probe immediately when SIGTERM is received.
Profiling in production
Enable pprof on a non-public port with authentication. Never expose it publicly — it reveals internal state and can be used to DoS the service.
Quick Check
Why should GOMAXPROCS be set based on container CPU limits rather than host CPUs?
Recap: Health Checks and Production Tuning
Key points:
- Liveness: process alive; Readiness: service can serve traffic
- automaxprocs sets GOMAXPROCS from container CPU limits
- GOMEMLIMIT prevents OOM kills; GOGC tunes GC frequency
- Expose metrics on a separate internal-only port
Frequently asked questions
Is the “Health Checks and Production Tuning” lesson free?
Yes — the full text of “Health Checks and Production Tuning” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Health Checks and Production Tuning”?
HEALTHCHECK, tini, signal handling in containers You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Health Checks and Production Tuning” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Multi-Stage Docker Builds for Go
- Environment Config and Secrets
- Docker Compose for Local Development
- Health Checks and Production Tuning