Target Groups and Health Checks
The fleet and the probe that watches it
Target groups define the fleet a balancer routes to; health checks are its eyes on that fleet. Correct health-check design (path, thresholds, interval) prevents draining live traffic to a half-dead box.
What you will learn
- Design a target group + health-check profile
- Tune interval/thresholds to match app behavior
- Explain draining and deregistration delays
A target group (AWS) / backend pool (Azure, GCP) holds instances behind a listener. Health checks probe an endpoint on your app; failures trip thresholds that remove targets from rotation and trigger replacement flows in autoscaling.
What is this?
AWS target groups: protocol+port, health-check settings (Path, IntervalSeconds, TimeoutSeconds, Healthy/UnhealthyThreshold). Azure backend pools: LB probes / App Gateway probes (path, interval, timeout, thresholds). GCP: backend services with instance group members + health checks (HTTP/HTTPS/TCP). Drain: deregistration delay (AWS), drain-mode, graceful shutdown — lets in-flight requests finish before a target is removed.
Why do you need it?
- Removing a flaky target prevents latency incidents before customers feel them.
- Autoscaling + health checks self-heal a fleet without tickets.
- Tuning thresholds avoids flapping (too eager) or zombie targets (too lazy).
- Draining makes deploys and failures graceful.
Mental model
A concierge checking which receptionists are at their desks (and not on a call) before sending guests
Health checks + draining
If a receptionist is away (health check fails), guests don't get sent there; when it's shift change (deploy), in-progress conversations (requests) are finished before their desk shuts.
How it works
- The balancer probes the health path on the health port every interval (default 30s).
- Success threshold on consecutive passes marks 'healthy'; failure threshold marks 'unhealthy'.
- Unhealthy targets leave rotation; the balancer returns to them only after recovery threshold.
- Draining/deregistration keeps existing connections alive for a delay while blocking new ones.
- Autoscaling uses the same health signal to terminate-and-replace groups.
Health-check lifecycle.
Examples
A sane health-check config
# AWS: target group health check tuned for slow cold-start appsaws elbv2 create-target-group --name web-tg --protocol HTTP \ --port 8080 --vpc-id vpc-12345 \ --health-check-protocol HTTP --health-check-path /healthz \ --health-check-interval-seconds 15 --health-check-timeout-seconds 5 \ --healthy-threshold-count 2 --unhealthy-threshold-count 3 \ --deregistration-delay-timeout-seconds 6015s interval, 2/3 thresholds, 60s drain: enough to avoid flapping while still catching dead targets quickly.
In production
- An ALB health check paths /internal/ready that also validates the DB connection pool (fail fast).
- App Gateway probes catch an app that accepts TCP but serves no HTTP (both checked).
- GCP backend with instance group + customized health check routes around a degrading shard.
Best practices
- Make the health endpoint cheap and deep enough: verify app liveness, not just OS liveness.
- Set interval ≥ app cold-start time and thresholds that tolerate loader spikes.
- Always set a drain/deregistration delay on services with in-flight work.
- Exclude health endpoints from access logs or rate them; they hammer every interval.
Common mistakes
- Health path that requires auth → balancer can't authenticate → flapping.
- Thresholds too eager: a 500ms blip removes a target, causing cascading load shifts.
- Zero drain delay on a service that processes jobs — mid-request kills.
- Probing TCP-only and missing an app that listens but never serves 200s.
Common issues
Targets test healthy via curl but balancer says unhealthyProbe port/interval mismatch or SG blocks the health port
Match probe port + protocol exactly; allow the health port from the LB SG.
Fleet flaps in wavesInterval too short vs app startup or a shared dependency outage
Lengthen interval/thresholds and check the shared dependency's health.
Debugging tips
- Use describe-target-health to see per-target state and reasons (e.g., 'unhealthy timeout').
- Curl the health path from the target's own host to separate app vs network issues.
- If targets flap together, the app depends on a shared downstream (DB) — check that first.
- Watch metrics: 'healthy host count' dropping during a release = deploy red flag.
Interview checkpoint
Hands-on lab
- Configure a target group with tuned health-check params
- Simulate threshold behavior with a small Python model
- Verify drain keeps in-flight requests safe
Design and Stress a Health-Check Profile
25 min · intermediate
Quick quiz
The balancer probes the health endpoint on the same port the app serves.