Chapter 19: Load Balancers
1. Why Load Balancing
Core problem: A single server has limited capacity (CPU, memory, network, connections). Load balancers distribute traffic across multiple servers for horizontal scaling, high availability, and single point of failure elimination.
| Benefit | Description | Example |
|---|---|---|
| Horizontal Scaling | Add more servers to handle increased load | 10 servers @ 1000 RPS each = 10k RPS capacity |
| High Availability | Server failure doesn't take down service | If 1 of 10 servers fails, 90% capacity remains |
| Zero-Downtime Deploys | Deploy to subset while others serve traffic | Rolling deployment: update 2 servers at a time |
| Geographic Distribution | Route users to nearest datacenter | US users β US DC, EU users β EU DC |
| Health-Based Routing | Avoid routing to unhealthy servers | Remove server with high error rate from pool |
2. Layer 4 vs Layer 7 Load Balancing
Key distinction: L4 operates at transport layer (TCP/UDP), L7 operates at application layer (HTTP/gRPC). Different visibility, capabilities, and performance characteristics.
| Aspect | Layer 4 (Transport) | Layer 7 (Application) |
|---|---|---|
| OSI Layer | Transport (TCP/UDP) | Application (HTTP/gRPC/WebSocket) |
| Visibility | IP, port, TCP flags | Headers, URL path, cookies, request body |
| Routing Decisions | IP hash, connection count | URL path, header, cookie, query param |
| Performance | ~1M RPS, <1ms latency | ~100k RPS, 1-5ms latency |
| SSL Termination | No (passthrough) | Yes (decrypt/inspect/re-encrypt) |
| Content-Based Routing | No | Yes (/api β service A, /images β service B) |
| Connection Handling | Single TCP connection end-to-end | Two connections (clientβLB, LBβserver) |
| Protocol Support | Any TCP/UDP protocol | HTTP/1.1, HTTP/2, HTTP/3, gRPC, WebSocket |
| Use Cases | High throughput, non-HTTP protocols, SQL DBs | Microservices, API gateways, HTTP routing |
| Examples | AWS NLB, HAProxy (TCP mode), IPVS | AWS ALB, Nginx, Envoy, HAProxy (HTTP mode) |
Direct Server Return (DSR)
L4 optimization where response bypasses load balancer and goes directly from server to client. Reduces LB bandwidth (only ingress traffic passes through LB). Requires server to have LB's VIP on loopback interface.
L4 vs L7 Architecture
3. Load Balancing Algorithms
Goal: Distribute load fairly and efficiently across backend servers. Different algorithms optimize for different goals: simplicity, fairness, statefulness, performance.
| Algorithm | How It Works | Pros | Cons | Use Case |
|---|---|---|---|---|
| Round Robin | Cycle through servers sequentially: 1β2β3β1 | Simple, stateless, fair if requests equal cost | Ignores server load/capacity, uneven if req cost varies | Homogeneous servers, uniform request cost |
| Weighted Round Robin | Assign weight to each server (2x weight = 2x traffic) | Accounts for heterogeneous capacity | Static weights, doesn't adapt to runtime load | Mixed instance types (m5.large + m5.2xlarge) |
| Least Connections | Route to server with fewest active connections | Adapts to actual load, good for long-lived conns | Requires state, doesn't account for request cost | WebSockets, streaming, database connections |
| Weighted Least Connections | Least connections + server weights | Combines capacity awareness + runtime load | More complex state tracking | Heterogeneous servers with long-lived conns |
| IP Hash | Hash client IP β deterministic server | Session affinity without cookies, simple | Uneven load if few clients, sticky on server failure | Sticky sessions for legacy apps |
| Consistent Hashing | Hash space (0-2^32) with virtual nodes, minimal rebalancing | Only K/N keys remap on server add/remove | More complex, uneven load without virtual nodes | Distributed caches (Memcached, Redis cluster) |
| Power of Two Choices | Pick 2 random servers, choose one with fewer connections | Near-optimal balance with O(1) cost, probabilistic fairness | Requires connection state | High-throughput L7 LBs (Envoy default) |
| Least Response Time | Route to server with lowest avg response time | Adapts to server performance degradation | Requires tracking latency metrics, can cascade failures | Heterogeneous backends with varying performance |
| Random | Pick random server for each request | Stateless, simple, no hotspots with many servers | Short-term imbalance possible | Stateless HTTP APIs with many backends |
Algorithm Comparison
Consistent Hashing Deep Dive
Maps keys and servers to a hash ring (0 to 2^32-1). Each key routes to the next server clockwise on the ring. When a server is added/removed, only ~1/N keys remap (vs 100% with naive hashing).
Hash: 100] --> B[Server B
Hash: 200] B --> C[Server C
Hash: 300] C --> A K1[Key 1
Hash: 150] -.->|Routes to| B K2[Key 2
Hash: 250] -.->|Routes to| C K3[Key 3
Hash: 50] -.->|Routes to| A end
Virtual nodes: Each physical server gets 100-500 virtual nodes on the ring to ensure even distribution. Without virtual nodes, servers could cluster and cause uneven load.
4. Health Checks
Purpose: Detect unhealthy servers and remove them from the load balancing pool. Prevent routing requests to failed/degraded instances.
| Type | How It Works | Pros | Cons | Example |
|---|---|---|---|---|
| TCP Health Check | Open TCP connection to port, close if successful | Fast, low overhead, works for any TCP service | Doesn't validate app logic, false positives | Connect to port 8080, if SYN-ACK received β healthy |
| HTTP Health Check | GET /health, expect 200 OK within timeout | Validates HTTP stack, can check dependencies | Slower than TCP, requires HTTP endpoint | GET /health returns 200 if DB reachable |
| gRPC Health Check | Call grpc.health.v1.Health/Check service | Standard for gRPC services, rich status info | Requires gRPC support, more complex | Check(service="myapp") β SERVING/NOT_SERVING |
| Active Health Check | LB periodically probes servers (every 5-30s) | Proactive detection, configurable thresholds | Extra load on servers, detection lag (5-30s) | Every 10s, fail after 3 consecutive failures |
| Passive Health Check | Monitor real request success/failure rates | No extra load, immediate detection on traffic | Requires traffic to detect, can miss issues | If 5 consecutive 5xx errors β mark unhealthy |
Health Check Parameters
| Parameter | Description | Typical Value | Tradeoff |
|---|---|---|---|
| Interval | Time between health checks | 5-30 seconds | Lower = faster detection but more load |
| Timeout | Max time to wait for response | 2-10 seconds | Lower = faster detection but false positives |
| Unhealthy Threshold | Consecutive failures before marking unhealthy | 2-5 checks | Lower = faster detection but less tolerance |
| Healthy Threshold | Consecutive successes before marking healthy | 2-10 checks | Higher = avoids flapping but slower recovery |
Connection Draining
Problem: When server marked unhealthy or removed, in-flight requests should complete gracefully.
Solution: Drain period (30-300s) where no new requests route to server, but existing connections allowed to finish. After drain timeout, forcibly close remaining connections.
Health Check Endpoint Design
// Good: Lightweight, checks critical dependencies
GET /health
Response 200 OK:
{
"status": "healthy",
"database": "connected",
"cache": "connected",
"uptime": 3600
}
Response 503 Service Unavailable:
{
"status": "unhealthy",
"database": "timeout",
"cache": "connected"
}
// Bad: Too expensive, causes cascading failures
GET /health β triggers full DB query + cache warmup
5. Session Affinity (Sticky Sessions)
Problem: Stateful applications store session data in memory. If user's requests load balance to different servers, session lost.
Solution: Ensure user's requests always route to the same server (sticky sessions), OR externalize session storage (preferred).
| Method | How It Works | Pros | Cons |
|---|---|---|---|
| Cookie-Based | LB sets cookie (e.g., AWSALB=server-id), routes based on cookie | Works across IPs, survives NAT, standard for HTTP | Requires cookie support, LB must parse HTTP |
| IP Hash | Hash(client IP) β deterministic server | Works at L4, no cookies needed | Breaks if client IP changes (mobile), uneven with NAT |
| Header-Based | Hash(User-Agent) or Hash(X-Session-ID) β server | Flexible, custom logic | Requires L7 LB, depends on client sending header |
| Application-Controlled | App generates token, encodes server ID, client sends in request | Most control, works with any LB algorithm | Requires app changes |
Sticky Sessions vs Externalized Sessions
| Aspect | Sticky Sessions | Externalized Sessions (Redis/DB) |
|---|---|---|
| Architecture | Session stored in server memory | Session stored in shared Redis/DB |
| Scalability | Limited (server failure loses sessions) | High (stateless servers, horizontal scaling) |
| High Availability | Low (server death = session loss) | High (sessions survive server failures) |
| Load Distribution | Uneven (users stuck to servers) | Even (any server handles any request) |
| Deployment | Complex (drain connections during deploy) | Simple (kill servers anytime) |
| Latency | Lower (in-memory access) | Higher (network call to Redis, ~1-5ms) |
| Cost | Lower (no external store) | Higher (Redis cluster costs) |
| Use Case | Legacy apps, WebSockets, small scale | Modern apps, cloud-native, high scale |
Session A in memory] LB1 -->|Always routes| S2[Server 2
Session B in memory] S1 -.->|If crashes| X[Sessions Lost] end subgraph "Externalized Sessions (Preferred)" C3[Client A] -->|Request| LB2[Load Balancer] C4[Client B] -->|Request| LB2 LB2 -->|Any request| S3[Server 1] LB2 -->|Any request| S4[Server 2] S3 <-->|Read/Write session| R[Redis Cluster] S4 <-->|Read/Write session| R end
6. SSL Termination
Key decision: Where to decrypt HTTPS traffic? Three models: terminate at LB, pass through to backend, or re-encrypt (bridge mode).
| Model | How It Works | Pros | Cons | Use Case |
|---|---|---|---|---|
| SSL Termination | LB decrypts HTTPS, forwards plain HTTP to backends | Simple, LB can inspect/route by content, reduced backend CPU | Plain HTTP in internal network (security risk), single cert location | Trusted internal network, cost-sensitive, need L7 routing |
| SSL Passthrough | LB forwards encrypted traffic (L4), backend decrypts | End-to-end encryption, backend controls certs | No L7 routing, higher backend CPU, can't inspect traffic | Zero-trust network, compliance (PCI-DSS), per-tenant certs |
| SSL Bridging (Re-encrypt) | LB decrypts, inspects, then re-encrypts to backend | L7 routing + end-to-end encryption | High CPU cost (2x crypto), complex config | Zero-trust + need L7 features, strict security |
no decrypt| S2[Server] S2 -->|Decrypt| S2 style LB2 fill:#9f9 end subgraph "SSL Bridging" C3[Client] -->|HTTPS| LB3[Load Balancer] LB3 -->|Decrypt| LB3 LB3 -->|Inspect| LB3 LB3 -->|Encrypt| LB3 LB3 -->|HTTPS| S3[Server] S3 -->|Decrypt| S3 style LB3 fill:#99f end
SSL Termination Flow
Certificate Management
| Aspect | Centralized (LB) | Distributed (Backends) |
|---|---|---|
| Certificate Storage | LB stores certs (AWS ACM, secrets manager) | Each server stores own cert |
| Renewal | Renew once at LB | Renew on all servers |
| SNI Support | LB can host multiple certs (SNI) | Each server independently handles SNI |
| Complexity | Low (single point) | High (N servers to manage) |
7. Global Server Load Balancing (GSLB)
Problem: Users worldwide need to route to nearest datacenter for low latency and high availability across regions.
Solution: DNS-based routing (GeoDNS), Anycast IP, or latency-based routing to direct users to optimal datacenter.
| Method | How It Works | Pros | Cons |
|---|---|---|---|
| GeoDNS | DNS server returns IP based on client's geographic location | Simple, works at DNS layer, no app changes | Coarse granularity (country-level), DNS caching delays failover (TTL) |
| Anycast | Same IP announced from multiple datacenters, BGP routes to nearest | Instant failover, true "nearest" routing via BGP, no DNS caching issues | Requires BGP peering, complex setup, stateful protocols break on failover |
| Latency-Based Routing | Route 53 measures latency, returns lowest-latency endpoint | Better than geo (accounts for network conditions), automatic | AWS-specific, DNS caching still an issue |
| Health-Based Failover | DNS returns primary DC, failover to secondary if primary unhealthy | Automatic DR, simple active-passive setup | Slow (DNS TTL delay), coarse failover |
GSLB Architecture
Cross-region replication)] S2 <-->|Replicate data| DB S3 <-->|Replicate data| DB
Anycast vs GeoDNS
203.0.113.10| C1 C1 -->|3. HTTP to 203.0.113.10| DC1[EU Datacenter] end subgraph "Anycast" C2[Client EU] -->|HTTP to 1.2.3.4| ANY[Internet
BGP Routing] ANY -->|Routes to nearest| DC2[EU Datacenter
1.2.3.4] ANY -.->|Also announces| DC3[US Datacenter
1.2.3.4] ANY -.->|Also announces| DC4[Asia Datacenter
1.2.3.4] end
Failover Strategies
| Strategy | Description | Failover Time | Use Case |
|---|---|---|---|
| Active-Passive | Primary DC serves traffic, secondary on standby | 1-5 minutes (DNS TTL) | Cost-sensitive, DR only |
| Active-Active | All DCs serve traffic, user routed to nearest | Instant (traffic re-routes to healthy DCs) | High availability, global users |
| Active-Active-Passive | Two DCs active (US, EU), one passive (Asia) | Instant for active DCs, 1-5min for passive | Regional presence + DR |
Route 53 Routing Policies
// Latency-based routing
example.com β Route 53
- US-East: 54.123.45.67 (latency: 10ms from client)
- EU-West: 18.234.56.78 (latency: 120ms from client)
β Returns 54.123.45.67
// Geolocation routing
Client from Germany β Returns EU IP
Client from USA β Returns US IP
Client from Brazil β Returns default (US IP)
// Weighted routing (canary / blue-green)
example.com:
- 90% β Production (v1.0)
- 10% β Canary (v2.0)
// Failover routing
Primary: US-East (healthy) β Return US IP
Primary: US-East (unhealthy) β Return EU IP
8. Software vs Hardware Load Balancers
Shift: Industry moving from expensive hardware LBs (F5, Citrix) to software LBs (HAProxy, Nginx, Envoy) and cloud-managed (AWS ALB/NLB).
| Load Balancer | Type | Layer | Performance | Cost | Use Case |
|---|---|---|---|---|---|
| HAProxy | Software | L4 + L7 | 1M+ conn, 100k RPS | Free | On-prem, high performance, full control |
| Nginx | Software | L7 | 50k RPS | Free (OSS) / Paid (Plus) | Web servers, reverse proxy, API gateway |
| Envoy | Software | L7 | 100k RPS | Free | Service mesh, microservices, modern observability |
| AWS ALB | Managed | L7 | Auto-scales | $0.008/hr + $0.008/LCU | AWS HTTP/gRPC, path-based routing, managed certs |
| AWS NLB | Managed | L4 | Millions RPS, <1ms | $0.0225/hr + $0.006/NLCU | Ultra-low latency, static IP, non-HTTP protocols |
| GCP Load Balancer | Managed | L4 + L7 | Auto-scales globally | Pay per GB | GCP, global anycast, CDN integration |
| F5 BIG-IP | Hardware | L4 + L7 | Very high | $50k-$500k | Legacy enterprise, advanced features, vendor support |
| Citrix ADC | Hardware | L4 + L7 | Very high | $30k-$300k | Enterprise, app acceleration, SSL offload |
| IPVS (Linux) | Software | L4 | Very high | Free | Kernel-level LB, Kubernetes kube-proxy (ipvs mode) |
Feature Comparison
| Feature | HAProxy | Nginx | Envoy | AWS ALB | AWS NLB |
|---|---|---|---|---|---|
| HTTP/2 | Yes | Yes | Yes | Yes | No (L4) |
| gRPC | Yes | Yes | Yes (native) | Yes | Yes (passthrough) |
| WebSocket | Yes | Yes | Yes | Yes | Yes |
| SSL Termination | Yes | Yes | Yes | Yes (ACM) | Yes (TLS) |
| Path-Based Routing | Yes | Yes | Yes | Yes | No (L4) |
| Host-Based Routing | Yes | Yes | Yes | Yes | No (L4) |
| Rate Limiting | Yes | Yes | Yes | No (use WAF) | No |
| Dynamic Config | Reload | Reload | Hot reload (xDS) | Automatic | Automatic |
| Observability | Logs, stats page | Logs, stub_status | Prometheus, tracing | CloudWatch | CloudWatch |
| Service Mesh | No | No | Yes (Istio data plane) | No | No |
Software LB Architecture
$200k, single point] HW --> S1[Servers] end subgraph "Modern (Software)" C2[Clients] --> LB1[HAProxy Instance 1] C2 --> LB2[HAProxy Instance 2] C2 --> LB3[HAProxy Instance 3] LB1 --> S2[Servers] LB2 --> S2 LB3 --> S2 DNS[DNS Round Robin] -.->|Distributes| LB1 DNS -.->|Distributes| LB2 DNS -.->|Distributes| LB3 end
9. High Availability of Load Balancers
Problem: Load balancer is a single point of failure. If LB dies, entire system is down.
Solution: Active-passive pairs with VRRP, active-active with DNS round robin, or BGP anycast for multi-LB resilience.
| Method | How It Works | Pros | Cons | Use Case |
|---|---|---|---|---|
| Active-Passive (VRRP) | Two LBs share virtual IP (VIP), active sends heartbeats, passive takes over on failure | Simple, fast failover (1-3s), standard protocol (VRRP/keepalived) | Passive wastes capacity, single region | On-prem, single DC, cost-sensitive |
| Active-Active (DNS RR) | DNS returns multiple IPs, client connects to any | Full capacity utilization, simple | DNS caching delays failure detection, uneven load | Stateless HTTP, tolerant of slow failover |
| BGP Anycast | Multiple LBs announce same IP via BGP, routers send to nearest | Instant failover, true active-active, multi-region | Requires BGP peering, complex, stateful conns break | Global CDNs, DDoS mitigation, DNS servers |
| Elastic/Managed LB | Cloud provider handles HA (AWS ALB/NLB multi-AZ) | Fully managed, auto-scales, multi-AZ by default | Vendor lock-in, less control | Cloud-native apps, rapid deployment |
VRRP (Active-Passive) Architecture
192.168.1.100| VIP[Virtual IP] VIP -.->|Owned by| LB1[LB1 Active
Priority 200] VIP -.->|Standby| LB2[LB2 Passive
Priority 100] LB1 -->|Heartbeat every 1s| LB2 LB1 -->|Routes traffic| S[Backend Servers] LB2 -.->|On LB1 failure| VIP2[Takes over VIP
ARP announcement] VIP2 -.->|Routes traffic| S
VRRP Failover Process
Multi-AZ AWS ALB Architecture
multi-AZ by default] ALB -->|Distributes| AZ1[Availability Zone 1
us-east-1a] ALB -->|Distributes| AZ2[Availability Zone 2
us-east-1b] ALB -->|Distributes| AZ3[Availability Zone 3
us-east-1c] AZ1 --> S1[Servers in AZ1] AZ2 --> S2[Servers in AZ2] AZ3 --> S3[Servers in AZ3] Note[AWS manages LB nodes
in each AZ automatically]
LB HA Comparison
| Aspect | VRRP (Active-Passive) | DNS RR (Active-Active) | BGP Anycast | AWS ALB |
|---|---|---|---|---|
| Failover Time | 1-3 seconds | 30-300 seconds (DNS TTL) | Instant (BGP convergence <1s) | Instant (managed) |
| Capacity Usage | 50% (passive idle) | 100% (all active) | 100% (all active) | 100% (auto-scale) |
| Complexity | Medium (keepalived config) | Low (DNS only) | High (BGP peering) | Low (managed) |
| Multi-Region | No (single VIP) | Yes (DNS per region) | Yes (anycast globally) | Yes (cross-region LB) |
| Stateful Connections | Breaks on failover | Unaffected (per-connection) | Breaks on failover | Breaks on failover |
10. Advanced Load Balancing Patterns
Rate Limiting
Protect backend from overload by limiting requests per client. Implemented via token bucket or leaky bucket algorithms.
| Algorithm | How It Works | Use Case |
|---|---|---|
| Token Bucket | Bucket holds N tokens, request consumes token, tokens refill at rate R/sec | Burst traffic allowed (up to bucket size) |
| Leaky Bucket | Requests enter queue, processed at fixed rate R/sec, overflow dropped | Smooth traffic, no bursts |
| Fixed Window | Allow N requests per time window (e.g., 1000/min) | Simple but allows 2N requests at window boundary |
| Sliding Window | Count requests in rolling time window (last 60 seconds) | More accurate than fixed window |
// Nginx rate limiting
http {
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/m;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
# Allow 100 req/min per IP, burst up to 20
}
}
}
Connection Draining
Gracefully remove servers from pool: stop sending new connections, allow existing to complete, timeout after drain period (e.g., 300s).
Canary Deployments
Route small percentage (1-10%) of traffic to new version, monitor errors, gradually increase if healthy.
| Stage | Canary % | Production % | Action |
|---|---|---|---|
| Initial | 1% | 99% | Deploy v2 to 1%, monitor for 30min |
| Expand | 10% | 90% | If healthy, increase to 10% |
| Half | 50% | 50% | If healthy, 50/50 split |
| Full | 100% | 0% | If healthy, complete rollout |
| Rollback | 0% | 100% | If errors, instant rollback |
10 servers] LB -->|10% traffic| CA[Canary v2.0
2 servers] M[Metrics] -.->|Monitor| CA M -.->|Error rate OK?| D{Decision} D -->|Yes| INC[Increase canary %] D -->|No| RB[Rollback to 0%]
Blue-Green Deployments
Two identical environments (blue=production, green=new version). Deploy to green, test, then switch LB to route 100% to green.
v1.0] G1[Green Environment
v2.0] -.->|Deployed, testing| G1 end subgraph "After Switch" LB2[Load Balancer] -->|100% traffic| G2[Green Environment
v2.0] B2[Blue Environment
v1.0] -.->|Standby for rollback| B2 end
| Pattern | Rollout | Rollback | Cost | Use Case |
|---|---|---|---|---|
| Rolling | Gradual (2 servers at a time) | Re-deploy old version | Low | Default for most apps |
| Canary | Gradual (1% β 10% β 50% β 100%) | Instant (change %) | Low | Risk-averse, need metrics |
| Blue-Green | Instant (flip LB) | Instant (flip back) | High (2x infra) | Zero-downtime, instant rollback critical |
A/B Testing via LB
Route users to different versions based on criteria (header, cookie, user ID) to compare behavior/performance.
// Envoy A/B routing
routes:
- match:
prefix: "/api"
headers:
- name: "X-Experiment"
exact_match: "variant-b"
route:
cluster: service_variant_b
- match:
prefix: "/api"
route:
weighted_clusters:
clusters:
- name: service_variant_a
weight: 50
- name: service_variant_b
weight: 50
Circuit Breaking at LB
LB detects backend failure patterns (high error rate, timeouts) and temporarily stops routing to unhealthy backend, preventing cascading failures.
(e.g., 50% errors in 10s) Open --> HalfOpen: After timeout (30s) HalfOpen --> Closed: Test requests succeed HalfOpen --> Open: Test requests fail note right of Open: Stop routing to backend, Fail fast, Prevents cascading failures
Retry and Timeout Policies
| Policy | Configuration | Purpose |
|---|---|---|
| Request Timeout | Max 5s per request | Prevent hanging requests |
| Retry Budget | Max 2 retries, only on 5xx/timeout | Improve reliability without overload |
| Retry Backoff | Exponential: 100ms, 200ms, 400ms | Avoid thundering herd |
| Idempotency | Only retry GET, PUT, DELETE (not POST) | Prevent duplicate operations |
Real-World Configurations & Benchmarks
Performance Benchmarks
| Load Balancer | Hardware | Connections | HTTP/1.1 RPS | L4 RPS | Latency |
|---|---|---|---|---|---|
| HAProxy | m5.2xlarge (8 vCPU) | 1.2M concurrent | 400K/sec | 1M/sec | <1ms |
| Nginx | m5.2xlarge (8 vCPU) | 500K concurrent | 300K/sec HTTP | N/A (L7 only) | 1-3ms |
| Nginx (HTTPS) | m5.2xlarge (8 vCPU) | 200K concurrent | 80K/sec | N/A | 3-5ms (TLS overhead) |
| AWS NLB | Managed (auto-scale) | Millions | 1M+ new conn/sec | 1M+/sec | <100ΞΌs added |
| AWS ALB | Managed (auto-scale) | 100K per target group | Auto-scales | N/A (L7) | ~3ms added |
AWS Limits & Characteristics
| Load Balancer | Key Limits | Details |
|---|---|---|
| AWS NLB | 1M+ new connections/sec, no IP warmup needed | Sub-100ΞΌs added latency. Static IPs. Cross-zone load balancing (charges apply). |
| AWS ALB | 100K concurrent connections per target group, 1000 rules limit | ~3ms added latency. Path-based/host-based routing. Auto-scaling (no warmup needed since 2019). |
Failure Timeline Example
Scenario: Backend server crashes behind a load balancer.
| Time | Event | Impact |
|---|---|---|
| T=0s | Server dies (crash, OOM, network partition) | New requests fail, in-flight requests dropped |
| T=10s | Health check fails (interval 5s Γ threshold 2) | LB marks server unhealthy, removes from pool |
| T=10s | New connections routed to healthy servers | New traffic unaffected after detection |
| T=30s | In-flight requests timeout (request timeout 30s) | Client receives 504 Gateway Timeout |
| Total Impact | 10s detection lag + 30s for existing connections | ~30s total impact for worst-case in-flight requests |
Summary
- Purpose: Horizontal scaling, HA, remove SPOF, enable zero-downtime deploys
- L4 vs L7: L4 = faster (TCP), L7 = smarter (HTTP routing). DSR for high bandwidth.
- Algorithms: Round Robin (simple), Least Connections (adaptive), IP Hash (sticky), Power of Two Choices (optimal), Consistent Hashing (caches)
- Health Checks: Active (periodic probes) + Passive (monitor real traffic). Connection draining for graceful removal.
- Session Affinity: Cookie/IP-based sticky sessions, but prefer externalized sessions (Redis) for scalability
- SSL Termination: Terminate at LB (simple), passthrough (end-to-end), re-encrypt (both)
- GSLB: GeoDNS (simple), Anycast (instant), latency-based routing. Active-active for HA.
- Software vs Hardware: HAProxy/Nginx/Envoy replaced F5. Cloud-managed (ALB/NLB) easiest. Envoy = service mesh standard.
- HA of LBs: VRRP (active-passive, 1-3s), DNS RR (active-active, slow), Anycast (instant, global), cloud-managed (multi-AZ)
- Advanced: Rate limiting, connection draining, canary/blue-green, circuit breaking, retry budgets
- Benchmarks: HAProxy (m5.2xlarge) = 1.2M connections, 400K HTTP/s. NLB = 1M+ conn/s, <100ΞΌs latency. Failure detection = 10s (health interval Γ threshold), total impact 30s with timeouts.