Markdown Editor

Load Balancing and Service Discovery Template (L4/L7, Health Checks)

Traffic path, L4 vs L7, balancing algorithms, active and passive health checks, discovery, capacity under failure, draining

System DesignStandardRFC 9110 HTTP Semantics; RFC 9113; RFC 2782loadbalancingservicediscovery

How to use: Use it when placing a service behind load balancers or changing how instances are found. Start with capacity under failure, then health checks and draining. The main pitfall is mixing liveness and readiness or removing instances without draining, which drops requests on every deploy.

Preview

Load Balancing and Service Discovery: [Service or platform]

Building-block decision record for spreading traffic across instances of a service and for finding those instances. It covers layer 4 versus layer 7 balancing, balancing algorithms, active and passive health checks, service discovery (DNS, registry, platform endpoints), connection draining and capacity under failure. HTTP behaviour follows RFC 9110 HTTP Semantics (STD 97, June 2022), with RFC 9112 and RFC 9113 for connection handling in HTTP/1.1 and HTTP/2; DNS SRV records follow RFC 2782. Concepts also draw on the power of two choices (Mitzenmacher, IEEE TPDS, 2001), the Maglev load balancer (Eisenbud et al., NSDI 2016), the gRPC health checking protocol and Kubernetes probe semantics. Replace every [bracketed] value and every row marked Example. Worked examples use Quillmere, an invented book-review and reading-list platform shared by the other building-block templates in this category.

Document control

FieldValue
Document ID[LB-REC-001]
Service[Example: reviews-api, HTTP/2 and gRPC, 12 instances]
Traffic sources[Example: Public API gateway, internal services]
Balancer layers[Example: Regional L4 network balancer, L7 proxy fleet, client-side balancing for gRPC]
Discovery mechanism[Example: Platform endpoints API with DNS for legacy clients]
Version[0.1]
Status[Draft / In review / Approved / Implemented / Superseded]
Owner[@platform-networking-lead]
Service owner[@reviews-lead]
Reviewers[@sre], [@security]
Last updatedYYYY-MM-DD
Classification[Internal]
RelatedAPI Gateway System Design (system-design/design-api-gateway), Resilience and Load Shedding Design (system-design/resilience-load-shedding-design), CDN System Design (system-design/design-cdn)

Approvals

RoleNameDecisionDate
Platform networking[@name][Approved / Changes requested]YYYY-MM-DD
Service owner[@name][Decision]YYYY-MM-DD
SRE[@name][Decision]YYYY-MM-DD

Revision history

VersionDateAuthorChange summary
0.1YYYY-MM-DD[@name]First draft
0.2YYYY-MM-DD[@name]Example: Added passive outlier detection after a 15 s error window during node failure

1. Traffic path

HopLayerBalancing unitHealth sourceOwner
Example: Regional L4 balancer4 (TCP, UDP)ConnectionTCP and HTTP check on proxiesPlatform
Example: L7 proxy fleet7 (HTTP/1.1, HTTP/2)RequestActive check plus passive outlier detectionPlatform
Example: gRPC client library7Request (call)Endpoints API plus gRPC health serviceService teams
[Hop][Layer][Unit][Source][Owner]

2. Layer 4 versus layer 7

ConcernL4L7
Unit of balancingConnection or flowRequest
Sees HTTP method, path, status codeNoYes
RetriesNot safely (cannot see requests)Can retry idempotent methods (RFC 9110 section 9.2.2)
Long-lived HTTP/2 or gRPC connectionsAll calls on a connection go to one instanceCalls spread across instances
TLSPassthrough or terminationUsually terminates to inspect requests
Cost and latencyLowerHigher per request

Retry rule, Example: the L7 proxy retries only methods that RFC 9110 defines as idempotent (GET, HEAD, OPTIONS, TRACE, PUT, DELETE) and only on connection failure or 503; POST is retried only when the request carries an idempotency key the service honours. Retries are capped at one per request and count against a retry budget (see system-design/resilience-load-shedding-design).

3. Balancing algorithm

AlgorithmHow it picksGood forWatch out for
Round robin (weighted)Next instance in turn, weighted by capacityUniform requestsSlow instances still get their share
Least outstanding requestsInstance with the fewest in-flight requestsUneven request costNeeds accurate counts per proxy
Power of two choicesSample two instances at random, pick the less loadedMany proxies with partial views; avoids herding onto one "best" instanceNeeds a load signal
Consistent hashing (ring, Maglev table)Hash of a key such as user ID or connection tupleAffinity, connection persistence across balancer changesHot keys load one instance
RandomUniform randomVery large fleets, simplicityHigher variance on small fleets

Mitzenmacher (2001) showed that choosing the less loaded of two random choices reduces the maximum load dramatically compared with one random choice. Maglev (NSDI 2016) uses consistent hashing plus connection tracking so that connections survive changes in the balancer fleet.

Decision: [Example: Least outstanding requests at the L7 proxy, power of two choices in the gRPC client library, slow start of 30 s for new instances.]

4. Health checks

SettingExample valueReason
Active checkGET /ready every 5 s, timeout 2 sCheap, no dependency calls
Unhealthy threshold3 consecutive failuresAvoid flapping on one slow reply
Healthy threshold2 consecutive successesQuick return after recovery
Passive outlier detectionEject after 5 consecutive 5xx or connection errors, for 30 s, at most 2 of 12 instances ejected at onceCloses the active-check window
gRPC servicesgrpc.health.v1 Health service, Check and Watch, status SERVING or NOT_SERVINGStandard protocol understood by clients
Kubernetes probesStartup probe for slow boot; readiness removes the pod from service endpoints; liveness restarts only on deadlockMatches the platform behaviour
Overload response503 with Retry-After (RFC 9110 sections 15.6.4 and 10.2.3)Balancer and clients back off

Detection window, Example: with a 5 s interval and 3 failures the balancer needs up to 15 s (17 s including the last 2 s timeout) to mark a crashed instance down. At 500 requests per second per instance that is up to 7,500 to 8,500 failed requests without passive detection; outlier detection after 5 errors cuts this to a few requests per proxy.

5. Service discovery

MechanismHow clients learnChange propagationStrengthsWeaknesses
DNS A/AAAA recordsResolve a nameBounded by TTL and client cachingUniversalClients and libraries may cache beyond TTL; no health detail
DNS SRV (RFC 2782)Resolve service name to host, port, priority, weightBounded by TTLPorts and weights in DNSLimited client support
Service registryInstances register and heartbeat; clients query or watchSecondsRich metadata, health awareRegistry must be highly available
Platform endpoints APIPlatform tracks ready pods; proxies and clients watchSecondsTied to readiness probesPlatform specific
Static configurationDeployed listOn redeploySimpleManual, error-prone
RuleExample decision
Source of truthPlatform endpoints, derived from readiness
DNS TTL for legacy clients30 s; legacy clients reconnect at least every 5 minutes
Discovery outageProxies and clients keep the last known list; never empty the list on a discovery error
Cross-zonePrefer same-zone instances while they hold at least 70% of capacity, then spill over

6. Capacity under failure

InputExample value
Peak load6,000 requests per second
Capacity per instance800 requests per second at p99 target
Safe utilisation70% (560 requests per second per instance)
Instances12
Capacity at safe utilisation12 x 560 = 6,720 requests per second
Load per instance, all healthy6,000 / 12 = 500 (62.5% of capacity)
Load per instance, 1 lost6,000 / 11 = 545 (68.2%)
Load per instance, 2 lost6,000 / 10 = 600 (75.0%), above safe utilisation
Minimum for N+1ceil(6,000 / 560) + 1 = 12 instances

With 12 instances spread 4 per zone, losing a whole zone leaves 8 instances at 750 requests per second each (93.8%), well above safe utilisation. [Example decision: accept degraded latency on zone loss and shed non-logged-in traffic first, or grow to 18 instances (6 per zone, 12 left after zone loss at 500 each, 62.5%, because at least ceil(6,000 / 560) = 11 survivors are needed), record in LB-03.]

7. Connection draining and deploys

SettingExample valueReason
Pre-stop delay5 s before closing listenersDiscovery and proxies observe removal first
Drain timeout30 sp99.9 request duration is 20 s
Long-lived streamsServer sends GOAWAY, client reconnects with backoff and jitterAvoid reconnect storm
Slow start for new instances30 s rampCold caches and JIT warm-up
Rolling deploy batch2 instances at a timeKeeps 10 of 12 serving; 600 per instance (75%) is accepted only during deploys outside peak

8. Decisions and open items

IDDecision or open itemReasonOwnerStatus
LB-01Example: L7 balancing for all HTTP/2 and gRPC trafficL4 pins long-lived connections@platform-networking-leadDecided
LB-02Example: Passive outlier detection on all proxies15 s active detection window@sreDecided
LB-03Example: Grow to 18 instances (6 per zone) for zone-loss toleranceZone loss puts survivors at 93.8%@reviews-leadOpen
LB-04Example: Health endpoint excludes shared database checkAvoid removing every instance on one dependency failure@reviews-leadDecided
[LB-NN][Item][Reason][@owner][Status]

Glossary and references

TermMeaning
L4, L7Balancing on transport connections versus on application requests
ReadinessWhether an instance should receive traffic now
LivenessWhether an instance should be restarted
Outlier detectionPassive removal of instances that return errors on real traffic
Connection drainingStopping new work for an instance while in-flight work completes
Slow startRamping traffic to a new instance gradually

References:

Standard and licence note

Based on RFC 9110, RFC 9112, RFC 9113 and RFC 2782 for protocol behaviour, and on the publicly available papers and project documentation cited above for balancing and health checking; no single standard governs load balancer design. The text, tables, numbers and examples are original to this collection, and Quillmere is an invented organisation. Check the current RFC status and the documentation of the balancer, platform and client libraries you use. Template licence: MIT.

Related templates