Load Balancing
A load balancer distributes incoming traffic across multiple backend servers, so no single server is overwhelmed and the system can scale and stay available. It's the linchpin of running anything at scale: the moment you need more than one server — for capacity or for redundancy — you need something in front of them deciding where each request goes. That something is a load balancer, and it's simultaneously how you scale horizontally and how you survive a server failure without downtime.
The load balancer does two jobs at once: spread the load (so you can add servers to handle more traffic) and route around failures (health-check backends and stop sending traffic to dead ones). Understanding the layer it operates at (L4 vs L7), the algorithm it uses to pick a server, and how it handles health checks and sessions covers the essentials for designing a resilient, scalable system.
TL;DR
- A load balancer spreads traffic across servers for scale and reliability.
- It enables horizontal scaling (add servers) and failover (route around dead ones).
- L4 balances by IP/port (fast); L7 balances by content (HTTP path/host — smarter).
- Health checks route around failures; stateless servers make balancing simple.
Quick Example
The load balancer sits in front, fanning requests out to healthy backends:
Why Load Balancing Matters
- Horizontal scaling — handle more traffic by adding servers behind the balancer, not by buying a bigger one. See Scalability Patterns.
- High availability — if a server fails, the balancer routes around it; no single point of failure in the app tier. See High Availability.
- Zero-downtime deploys — drain and replace servers behind the balancer one at a time.
- Efficiency — keep all servers evenly utilized rather than some idle and some overloaded.
L4 vs L7
Load balancers operate at different network layers (see TCP/IP):
- Layer 4 (transport) — balances by IP address and port, without inspecting the content. Very fast and protocol-agnostic, but "dumb" — it can't route by URL or host.
- Layer 7 (application) — inspects the HTTP request (path, host, headers, cookies) and routes accordingly. Smarter — enables path-based routing, host-based routing, SSL termination, and content-aware decisions — at slightly higher cost.
Most web apps use an L7 load balancer (or both: L4 for raw throughput, L7 for routing). See Cloud Networking for cloud load balancers.
Balancing Algorithms
Least connections is a strong default for varied request durations; round robin is simplest; IP hash provides stickiness when needed.
Health Checks & Sessions
- Health checks — the balancer periodically probes each backend (e.g. a
/healthendpoint); failing servers are removed from rotation and re-added when healthy. This is what turns "a server died" into a non-event. - Sessions / stickiness — because HTTP is stateless and a user's requests may hit different servers, either keep servers stateless (store session state in a shared store like Redis — the preferred approach) or use sticky sessions (the balancer routes a user to the same server). Stateless is more resilient; stickiness complicates failover.
Best Practices
- Keep servers stateless — store session/state externally so any server can handle any request.
- Use health checks with a real readiness endpoint so failures are routed around automatically.
- Choose L7 for content-aware routing; L4 for raw speed.
- Spread across availability zones so a zone failure doesn't take everything down (see High Availability).
- Pick the algorithm to fit — least connections for uneven request durations, round robin for uniform.
Common Mistakes
Stateful servers with naive balancing
No health checks
FAQ
What's the difference between L4 and L7 load balancing?
Layer 4 load balancing operates at the transport layer, routing traffic by IP address and port without looking at the content of the request. It's very fast and works for any protocol, but it can't make content-based decisions. Layer 7 load balancing operates at the application layer, inspecting the HTTP request — URL path, host, headers, cookies — so it can do path-based routing ("/api → API servers"), host-based routing, SSL termination, and other content-aware logic, at a modest performance cost. Most web applications use L7 for its flexibility; high-throughput or non-HTTP workloads may use L4, and some architectures combine both.
How does a load balancer improve reliability, not just scale?
Through health checks and failover. The balancer continuously probes each backend (typically hitting a /health endpoint), and when a server fails the check, it's automatically removed from rotation so no traffic reaches the dead server — users never notice. When the server recovers, it's added back. This turns a server crash from an outage into a non-event, and it enables zero-downtime deploys (drain a server, update it, return it to rotation). Combined with spreading servers across availability zones, load balancing is the foundation of high availability for the application tier, not just a tool for distributing load.
What balancing algorithm should I use?
It depends on your traffic. Round robin (each server in turn) is simplest and fine when requests are roughly uniform. Least connections (send to the server with the fewest active connections) is a strong default when request durations vary, since it avoids piling work on a server still busy with long requests. Weighted variants account for servers of different capacity. IP hash provides stickiness (same client → same server) when you need it. For most web apps, least connections or round robin works well; choose based on whether your requests are uniform or highly variable in duration.
What are sticky sessions and should I use them?
Sticky sessions (session affinity) make the load balancer route a given user's requests to the same backend server every time, usually so that server's in-memory session data stays accessible. The better alternative is to keep servers stateless — store session state in a shared external store (Redis, a database) so any server can handle any request. Stateless is more resilient (a server failing doesn't log users out or lose their session) and makes scaling and deploys cleaner. Use sticky sessions only when you genuinely can't externalize state; they complicate failover and can unbalance load. Stateless-with-shared-store is the recommended default.
Related Topics
- Scalability Patterns — Horizontal scaling
- High Availability — Failover and redundancy
- Cloud Networking — Cloud load balancers
- TCP/IP — The layers L4/L7 refer to
- HTTP & Web Protocols — What L7 balancers inspect