AnyLearn
All lessons
Computer Scienceintermediate

Load Balancing

How load balancers spread traffic across servers, what L4 and L7 actually mean, the routing algorithms in real use, and the failure modes you need to design around.

Not signed in โ€” your progress and quiz score won't be saved.
Lesson progress1 / 8

What load balancing actually does

A load balancer sits between clients and a pool of backend servers, deciding which server handles each incoming request. Its three jobs:

  1. Distribute work so no single server is overloaded while others idle.
  2. Hide failures: if a backend dies, the LB stops sending it traffic.
  3. Decouple addressing โ€” clients only know one endpoint, even if backends come and go.

The payoff is horizontal scaling. Add a server to the pool, it absorbs a slice of traffic immediately. Lose a server, traffic redistributes. Without a load balancer, every backend change requires touching every client.

Full lesson text

All 8 steps on one page โ€” for reading, reference, and search.

Show

1. What load balancing actually does

A load balancer sits between clients and a pool of backend servers, deciding which server handles each incoming request. Its three jobs:

  1. Distribute work so no single server is overloaded while others idle.
  2. Hide failures: if a backend dies, the LB stops sending it traffic.
  3. Decouple addressing โ€” clients only know one endpoint, even if backends come and go.

The payoff is horizontal scaling. Add a server to the pool, it absorbs a slice of traffic immediately. Lose a server, traffic redistributes. Without a load balancer, every backend change requires touching every client.

2. Layer 4 vs Layer 7

Load balancers operate at one of two networking layers, and the difference matters:

  • Layer 4 (transport): decides based on IP + port. Fast, cheap, protocol-agnostic. Can't inspect HTTP โ€” it just shuttles TCP/UDP packets.
  • Layer 7 (application): parses HTTP. Can route by URL path, headers, cookies, content type. Can terminate TLS, modify requests, do compression.

L4 is what you use for raw throughput (databases, custom protocols). L7 is what you use for web traffic where routing by /api/... vs /static/... matters. Most modern apps end up with both: an L4 in front of an L7 fleet, or just an L7 (NGINX, HAProxy, Envoy, AWS ALB).

3. Routing algorithms in real use

How does the LB pick a backend? Common algorithms:

  • Round robin: rotate through servers in order. Simple, fair, ignores actual load.
  • Least connections: send to whichever backend has fewest active connections. Better when requests have variable duration.
  • Least response time: factor in measured backend latency. Self-correcting; punishes slow nodes.
  • IP hash / consistent hashing: hash the client IP to pick a backend. Same client โ†’ same backend. Useful for caches and stateful workloads.
  • Weighted variants: give bigger servers a higher slice (e.g. "this 16-core box gets 3x weight").

Default to least-connections for most web traffic. Use consistent hashing when locality matters (cache affinity).

4. Layer 7 load balancer in front of an app fleet

One front door, many backends, health-checked.

flowchart LR
  Client["Client"] --> LB["L7 Load balancer"]
  LB --> S1["Server 1"]
  LB --> S2["Server 2"]
  LB --> S3["Server 3"]
  Health["Health checks"] --> S1
  Health --> S2
  Health --> S3
  Health --> LB

5. Health checks and quick removal

A load balancer is only as good as its health check. Two flavours:

  • Active: the LB pings each backend periodically (GET /health every 5s). Misses force removal.
  • Passive: the LB watches the responses to real traffic; a sudden spike of 5xx pulls the backend.

Good practice:

  • The health endpoint should test the actual work path (DB connectivity, dependencies), not just return 200.
  • Mark a backend unhealthy on 2-3 consecutive misses, not 1 โ€” transient blips happen.
  • Mark it healthy again only on multiple consecutive successes โ€” flapping nodes are worse than dead ones.
  • Include the LB's own health in your observability โ€” "the LB thinks server X is down" is the answer to many incidents.

6. Sticky sessions: when and why

By default an LB sends each request to whichever backend is currently best. But some apps store session state in memory on a single server. If the next request from the same user hits a different backend, the session is gone.

Sticky sessions (session affinity) solve this by binding a user to one backend, usually via a cookie the LB injects or by hashing the client IP.

It works, but it has costs: uneven load (whales stick to one server), no graceful failover (if their pinned server dies, the session is gone anyway), harder rolling deploys. The clean fix is to move session state to a shared store (Redis, the DB) so any backend can handle any request. Sticky sessions are the workaround; stateless backends are the goal.

7. Failure scenarios to plan for

What goes wrong, and what you do:

  • A backend dies: health checks pull it. Other backends absorb its traffic. If you were running at >50% capacity per node, the survivors get crushed โ€” provision headroom (typically run at <70%).
  • The LB itself dies: deploy LBs in pairs/clusters with a VIP or DNS failover. AWS ALB, GCP HTTPS LB, Cloudflare are clustered for you.
  • Backends are slow, not dead: health checks pass, latency spikes. Configure circuit breakers so the LB stops sending traffic to slow nodes before they cascade.
  • Thundering herd on a restart: a node restarts and gets full prod traffic immediately. Use slow-start (Envoy, ALB support it) so traffic ramps up over 30โ€“60s while caches warm.

8. When you don't need a load balancer

Counter-intuitively, plenty of services don't need an LB:

  • Serverless platforms (Lambda, Cloud Run, Vercel) load-balance for you โ€” sending more requests just spawns more instances.
  • Single-instance services (cron jobs, internal admin panels) don't benefit until they outgrow one box.
  • Backend-to-backend RPC is often better served by client-side load balancing (gRPC + service discovery, where the client maintains its own pool) โ€” avoids the extra network hop.

The useful question: am I scaling out, or just one big instance? If it's the latter, skip the LB until it's not.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. Which load-balancing algorithm best handles requests with highly variable durations?
    • Round robin
    • Least connections
    • Random
    • First-fit
  2. What's the main reason teams use sticky sessions, and what's the better long-term fix?
    • To save bandwidth โ€” move sessions into the URL
    • Because backends keep session state in memory โ€” fix by moving state to a shared store like Redis
    • To enforce security โ€” encrypt cookies
    • Sticky sessions improve cache hit rates
  3. Your team runs at 90% capacity on three servers behind an LB. One dies. What's likely to happen, and what should you have done?
    • Nothing โ€” LBs handle this seamlessly
    • The two survivors get crushed at 135% load each; provision headroom (run at <70%)
    • DNS will mask the failure
    • Sticky sessions will save you
  4. Which task is *only* possible at Layer 7 (not L4)?
    • Round-robin distribution
    • Health checks
    • Routing by URL path (e.g. /api โ†’ service A, /static โ†’ service B)
    • TLS termination
  5. A server restarts and the LB immediately sends it full production traffic. The server falls over. What's the standard mitigation?
    • Disable health checks for 10 minutes
    • Slow-start: ramp traffic up over 30-60 seconds after the server returns
    • Remove the server from the pool permanently
    • Add more servers

Related lessons