go 56 lines · 7 steps

Liveness vs readiness health checks in Gin

A Gin handler that separates 'is the process alive' from 'can it actually serve traffic' by pinging its dependencies.

Explained by highlit
1package handlers
2 
3import (
4 "context"
5 "net/http"
6 "time"
7 
8 "github.com/gin-gonic/gin"
9 "github.com/redis/go-redis/v9"
10 "gorm.io/gorm"
11)
12 
13type HealthHandler struct {
14 DB *gorm.DB
15 Redis *redis.Client
16}
17 
18func RegisterHealthRoutes(r *gin.Engine, h *HealthHandler) {
19 group := r.Group("/health")
20 {
21 group.GET("/live", h.Liveness)
22 group.GET("/ready", h.Readiness)
23 }
24}
25 
26func (h *HealthHandler) Liveness(c *gin.Context) {
27 c.JSON(http.StatusOK, gin.H{"status": "ok"})
28}
29 
30func (h *HealthHandler) Readiness(c *gin.Context) {
31 ctx, cancel := context.WithTimeout(c.Request.Context(), 2*time.Second)
32 defer cancel()
33 
34 checks := gin.H{"database": "ok", "redis": "ok"}
35 ready := true
36 
37 if sqlDB, err := h.DB.DB(); err != nil || sqlDB.PingContext(ctx) != nil {
38 checks["database"] = "unavailable"
39 ready = false
40 }
41 
42 if err := h.Redis.Ping(ctx).Err(); err != nil {
43 checks["redis"] = "unavailable"
44 ready = false
45 }
46 
47 status := http.StatusOK
48 if !ready {
49 status = http.StatusServiceUnavailable
50 }
51 
52 c.JSON(status, gin.H{
53 "ready": ready,
54 "checks": checks,
55 })
56}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Liveness answers whether the process is running while readiness answers whether it can serve requests, and they deserve separate endpoints.
  2. 2Bounding dependency checks with a context timeout stops a hung database or cache from making the probe itself hang.
  3. 3Returning 503 when any dependency is down lets orchestrators route traffic away instead of failing user requests.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Liveness vs readiness health checks in Gin — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code