Load Balancing

Spread requests over many servers and route around dead ones: layer 4 vs 7, algorithms, health checks, sticky sessions and a balancer that stays up.

14 minLesson 2 of 6
On this page
  1. The idea
  2. Spreading requests and surviving a crash
  3. Layer 4 or layer 7
  4. Choosing a server
  5. Sticky sessions and stateless servers
  6. When the balancer is the weak point
  7. Numbers worth remembering
  8. In the interview
  9. Common mistakes
  10. What to practise next

Launch day: the API expects 3,000 requests a second at peak, and one app server handles about 1,000 before its latency climbs. So you need at least three servers. But clients know one address, and when one of those servers crashes mid-afternoon, somebody has to stop sending it traffic.

The idea

A load balancer sits in front of many identical servers and owns the public address; it picks a server for each request or connection. That gives you two things at once: capacity, because you scale by adding servers behind it, and availability, because a dead server is taken out of the pool.

It costs an extra hop (under a millisecond inside a data center), one more component that must not fail, and a rule: any server must be able to handle any request. That rule is what "stateless" means.

Clients reach one virtual IP. The active balancer spreads requests over the app servers; the standby takes the IP over if the active one stops sending heartbeats. Session data lives in a shared store, so any server can serve any user.Clients to Load balancer (active) (virtual IP); Load balancer (active) and Load balancer (standby) (heartbeat); Load balancer (active) to App servers; App servers to Session store; App servers to Database.ClientsLoad balancer(active)Load balancer(standby)App serversSession storeDatabasevirtual IPheartbeat
Clients reach one virtual IP. The active balancer spreads requests over the app servers; the standby takes the IP over if the active one stops sending heartbeats. Session data lives in a shared store, so any server can serve any user.

Spreading requests and surviving a crash

Run four servers, not three, so losing one still leaves enough. Each then gets 3,000 ÷ 4 = 750 requests a second. Step through round robin, then a crash.

Round robin over four servers, then server C diesUse the arrows or ← → keys
  1. Round robin over four servers, then server C dies, step 1Clients to Load balancer; Load balancer to Server A; Load balancer to Server B; Load balancer to Server C; Load balancer to Server D.ClientsLoad balancerServer AServer BServer CServer D
    next
    B
    rps per server
    750

    1Request 1 arrives. Round robin hands requests to servers in turn, so it goes to A.

  2. Round robin over four servers, then server C dies, step 2Clients to Load balancer; Load balancer to Server A; Load balancer to Server B; Load balancer to Server C; Load balancer to Server D.ClientsLoad balancerServer AServer BServer CServer D
    next
    A
    rps per server
    750

    2Requests 2, 3 and 4 go to B, C and D. Each server gets 750 of the 3,000 a second.

  3. Round robin over four servers, then server C dies, step 3Clients to Load balancer; Load balancer to Server A; Load balancer to Server B; Load balancer to Server C; Load balancer to Server D.ClientsLoad balancerhealth checkServer AServer BServer CServer D
    next
    A
    rps per server
    750

    3Every 5 seconds the balancer calls GET /health on each server. All four answer 200, so all stay in the pool.

  4. Round robin over four servers, then server C dies, step 4Clients to Load balancer; Load balancer to Server A; Load balancer to Server B; Load balancer to Server C; Load balancer to Server D.ClientsLoad balancerServer AServer BServer CrefusedServer D
    next
    D
    rps per server
    750

    4Server C's process crashes. The balancer does not know yet, and the next request for C gets connection refused.

  5. Round robin over four servers, then server C dies, step 5Clients to Load balancer; Load balancer to Server A; Load balancer to Server B; Load balancer to Server C; Load balancer to Server D.ClientsLoad balancerServer AServer BServer CdownServer Dretry
    next
    A
    rps per server
    750

    5The request never reached a server, so the balancer can safely retry it on D. A request that timed out after reaching C is different: retry it only if it is idempotent.

  6. Round robin over four servers, then server C dies, step 6Clients to Load balancer; Load balancer to Server A; Load balancer to Server B; Load balancer to Server C; Load balancer to Server D.ClientsLoad balancerServer AServer BServer Cout of poolServer D
    next
    A
    rps per server
    750

    6C fails two health checks in a row and is marked down, at most about 10 seconds after the crash. Without retries, a quarter of requests would fail in that window: up to 750 × 10 = 7,500 errors.

  7. Round robin over four servers, then server C dies, step 7Clients to Load balancer; Load balancer to Server A; Load balancer to Server B; Load balancer to Server C; Load balancer to Server D.ClientsLoad balancerServer A1,000/sServer B1,000/sServer CdownServer D1,000/s
    next
    B
    rps per server
    1000

    7Now A, B and D share the load: 3,000 ÷ 3 = 1,000 each, exactly their limit. The fourth server was not waste; it was what kept the site up.

1 / 7

Health checks come in two kinds. Active checks call an endpoint on a timer, as above. Passive checks watch real traffic and eject a server that returns errors or times out, which catches problems faster.

Layer 4 or layer 7

What the balancer can see
OptionGood atBad atPick it when
Layer 7 (HTTP) Usual defaultReads each request: routes by path or header, terminates TLS, retries, balances each request separately even when they share a connection.More CPU and a little more latency per request. Only works for protocols it understands.Web apps and APIs. The usual answer.
Layer 4 (TCP/UDP)Forwards connections by IP and port without reading them. Very fast, works for any protocol.Cannot route by URL or retry a single request. A long-lived connection stays on one server, however busy it gets.Non-HTTP traffic, huge connection counts, or when TLS must pass through untouched.

Choosing a server

Balancing algorithms
OptionGood atBad atPick it when
Round robin Usual defaultSimple and even when requests cost about the same. Weighted round robin gives bigger servers more.Ignores load: a server stuck on slow requests keeps getting its full share.Short, similar requests. The default.
Least connectionsSends work to the server with the fewest open connections, so slow requests do not pile up.Needs per-server counts. A new empty server can be flooded at first.Request times vary a lot, or connections are long-lived (WebSockets).
Hash of a keyThe same user or key always lands on the same server, which keeps its local cache warm.Hot keys make hot servers. Adding a server moves keys unless you use consistent hashing.Per-key locality matters: cache shards, a user's in-memory state.

Hashing is where consistent hashing comes in: with a plain hash % n, going from 4 to 5 servers moves about 4 keys in 5 to a different server.

Sticky sessions and stateless servers

If server A keeps your shopping cart in its own memory, every request from you must reach A. Balancers can do that with sticky sessions, usually a cookie naming the server. But load gets uneven, and when A dies the carts on it are gone.

The better answer is stateless servers: keep session data in a shared store (an in-memory store such as Redis) or in a signed token the client sends. Then any server can handle any request, a crash loses nothing, and you add or remove servers freely.

When the balancer is the weak point

One balancer in front of everything is a single point of failure. The usual fix is the pair in the first diagram: an active and a standby that share a virtual IP, with the standby taking the IP when heartbeats stop. At larger scale, run several active balancers and spread clients over them with DNS returning several addresses, or with one address announced from many places (anycast). Managed cloud balancers already do this; say so rather than drawing it.

Reverse proxies and API gateways sit in the same spot. A reverse proxy receives requests on behalf of servers: it terminates TLS, compresses and caches. A layer 7 load balancer is a reverse proxy that spreads load. An API gateway is a reverse proxy with API concerns added: authentication, rate limiting, and routing /orders and /users to different services. In a diagram, one box labelled "API gateway / load balancer" is fine.

Numbers worth remembering

  • Worst-case detection time is check interval × failures needed: 5 s × 2 = about 10 s.
  • Servers needed: peak requests ÷ per-server capacity, rounded up, plus at least one spare.
Estimate: How many app servers

How many app servers do you run so the peak is still served after one server fails?

You know
  • 2,000 requests a second on average
  • Peak is 3 times the average
  • One server handles 500 requests a second at a healthy load

Show the working
  1. Peak: 2,000 × 3 = 6,000 requests a second
  2. Servers at peak: 6,000 ÷ 500 = 12
  3. One spare for a failure: 12 + 1 = 13

Estimate 13 (anything from 6 to 40 is a good answer)

With several zones, size so losing a whole zone still leaves enough: more spare than one server.

In the interview

Draw a load balancer as soon as you have more than one server, then name the choices it implies: "Layer 7, round robin, health checks every few seconds, and the app servers are stateless, with sessions in a shared store, so I can scale them freely."

Sessions behind a balancerWeak answer
Interviewer

Users keep getting logged out. Why might that be?

You

We could turn on sticky sessions so each user stays on one server.

Sessions behind a balancerStrong answer
Interviewer

Users keep getting logged out. Why might that be?

You

Sounds like sessions live in each server's memory and the balancer sends the next request elsewhere. I'd move sessions to a shared store, so any server can read them and a server restart loses nothing. Stickiness can stay as a cache-warmth hint, not as the place the data lives.

Follow-ups to expect:

  • "What if the load balancer dies?" Active-standby pair sharing a virtual IP, or several active ones behind DNS or anycast.
  • "How do you deploy without dropping requests?" Take a server out of the pool, let in-flight requests finish (draining), update it, put it back.
  • "WebSockets behind a balancer?" Least connections, since each connection lasts hours, and plan for clients reconnecting when a server goes away.

Common mistakes

Quick check

Health checks run every 10 seconds and a server is marked down after 3 failures in a row. It crashes while taking 400 requests a second, and the balancer does not retry. About how many requests fail?

A chat service keeps WebSocket connections open for hours, and some users are much more active than others. Which balancing algorithm fits?

You need to route /api/orders to one service and /api/users to another. What do you need?

What to practise next

Once requests reach your servers, the next win is not doing the same work twice: Caching. To see a balancer in front of separate read and write paths, work through Design a URL Shortener.