A traffic director that spreads requests across identical backend servers so none is overwhelmed — using a strategy plus health checks.
A load balancer sits in front of a pool of identical backend servers (upstreams) and spreads incoming requests across them so no single one is overwhelmed. It's the piece that turns *one server* into *a fleet* — the foundation of horizontal scaling. Two things define it: the strategy that picks a server, and the health checks that keep dead servers out of rotation.
hash % N would cause when the pool changes.Load balancers operate at one of two layers. Layer 4 (transport) balances on TCP/UDP: it sees IP addresses and ports, forwards packets fast, and never inspects the payload — cheap and protocol-agnostic. Layer 7 (application) understands HTTP: it can route on URL path, headers, or cookies (/api/* to one pool, /images/* to another), terminate TLS, and retry failed requests — smarter, but more work per request.
Client --> [ Load Balancer ]
| strategy picks a healthy server
+-----------+-----------+
v v v
server1 server2 server3
(healthy) (healthy) (FAILED - pulled from rotation)
L4: routes on IP:port (fast, opaque)
L7: routes on HTTP path, (smart: /api -> pool A,
headers, cookies /img -> pool B)A load balancer must never send traffic to a dead server. It runs periodic health checks — probing each upstream (GET /healthz returning 200, or a TCP connect) on an interval. A server that fails a few consecutive checks is pulled from rotation; when it passes again it's added back. This is what makes a fleet self-healing: a crashed server simply stops receiving requests, and users never notice.