CMD Guide
HomeSystem DesignLoad Balancing

Load Balancing Algorithms

A load-balancing algorithm is the decision rule a balancer runs on every incoming request to choose which backend serves it — and the only thing that separates the ten famous algorithms is how much live state about the backends that rule is allowed to consult: nothing at all (a fixed rotation), a client identifier (hashing), or real-time health signals (open connections, latency, bandwidth). Everything below is a point on that spectrum.

Rather than memorise ten near-identical pros/cons lists, decide with four axes. Almost every real choice falls out of them:

The tree below is the whole page in one picture.

diagram
diagram

Traced: why "blind rotation" quietly overloads a server

The gap between Round Robin and Least Connections is invisible until request lifetimes differ — which they always do in reality (a file upload holds a connection far longer than a health check). Here is the same stream fed to both, on three identical backends S1, S2, S3.

Setup: six requests arrive one per tick. Two are long-lived (hold the connection open for the rest of the window); four are short (finish inside their own tick). The long ones arrive at tick 1 and tick 4. Least Connections picks the server with the fewest currently-open connections, breaking ties by lowest index.

TickRequestRound Robin picksLeast Connections picks (open counts before)
1R1 (long)S1S1  (0,0,0 → tie, S1)
2R2 (short)S2S2  (1,0,0)
3R3 (short)S3S2  (1,0,0 → S2 lowest idle)
4R4 (long)S1 ← 2nd long conn!S2  (1,0,0)
5R5 (short)S2S3  (1,1,0)
6R6 (short)S3S3  (1,1,0)

Persistent load left behind:

That is the entire argument for load-aware balancing: identical hardware plus a blind rule still produces a hot server the moment request costs stop being uniform.

The ten algorithms, on one page

Each row is a mechanism plus where it lands on the axes. The families matter more than the names.

AlgorithmMechanism (the rule)Load-aware?Sticky?Best when
Round RobinCyclic: server[i], i = (i+1) mod nNoNoHomogeneous, stateless, uniform cheap requests
Weighted Round RobinSame, but each server appears in the cycle in proportion to its weightNo (static weights)NoHeterogeneous hardware, predictable load
RandomPick a server uniformly at randomNoNoHomogeneous; want O(1) with zero shared state (great for many independent balancers)
Power-of-two-choicesSample 2 servers uniformly at random, send to the one with fewer active requestsYes (samples load)NoMany independent balancer replicas at scale; want near-LC balance without a global least-loaded structure
Least ConnectionsFewest currently-open connectionsYes (connections)NoLong-lived / variable-duration requests
Weighted Least ConnectionsMinimise connections ÷ weightYesNoHeterogeneous and variable load
Least Response TimeLowest recent latency (often × connections)Yes (latency)NoLatency-critical services; backends of differing speed
Least BandwidthServer currently pushing the fewest MbpsYes (throughput)NoStreaming, large downloads, CDNs
IP Hashserver = hash(client IP) mod nNoYes (by IP)Need affinity at L4 with no cookie available
Custom / metric-basedWeighted score over CPU, memory, queue depth, app metricsYes (composite)ConfigurableStandard rules fail; you have a real bottleneck metric to optimise

Read top-to-bottom, the table is just the spectrum again: static → load-aware → hashed → fully custom, trading simplicity for adaptivity at each step.

Power-of-two-choices sits between Random and Least Connections: it pays two lookups instead of a full scan and, at large n, bounds the maximum load to ~log log n growth instead of log n / log log n for plain random — see the traced companion page for it beating both Round Robin and naive Least Connections on the same request stream.

Why IP-hash breaks on a resize — the road to consistent hashing

IP Hash's appeal is that it needs no state: server = hash(clientIP) mod n deterministically pins a client to a backend. Its fatal flaw is the mod n. Change n — add one server, or lose one to a crash — and nearly every client remaps. Trace four clients across a 3→4 scale-up:

Clienthash3 servers: hash % 34 servers: hash % 4Result
C1172 → S21 → S1moved
C2232 → S23 → S3moved
C3180 → S02 → S2moved
C4120 → S00 → S0stayed

3 of 4 clients jumped servers by adding a single node. That is not bad luck — plain modulo remaps on the order of (n-1)/n of all keys on any resize. For sticky sessions that means mass logout; for a sharded cache it means a near-total cache flush and a thundering herd onto the origin exactly when you were trying to add capacity.

Consistent hashing fixes this: it places servers and keys on a hash ring, so adding or removing a node only remaps the keys in that node's arc — about 1/n of keys, not (n-1)/n. This is why every serious affinity/sharding system (Cassandra, DynamoDB, memcached clients, Envoy's ring-hash) uses consistent hashing rather than mod n. See the dedicated Consistent Hashing lesson for the ring construction and virtual nodes.

Pitfalls

When to use which — and what it costs

The senior move is to start with the cheapest rule that satisfies your constraints and only climb the spectrum when a real signal forces it.

Round Robin vs Least Connections vs Consistent Hashing in one line: Round Robin is free but blind; Least Connections adapts to real load at the price of per-server state; consistent hashing buys you stable affinity at the price of giving up load-awareness entirely. The best real systems layer them — e.g. an L7 balancer doing weighted least-connections within a group, and consistent hashing to pick the group for a sharded key.

Interviewer follow-ups — model answers

  1. "Why not always Least Response Time?"
    Bar: It herds: the momentarily fastest node absorbs all new traffic until it slows, then the herd stampede to the next — sawtooth load unless you EWMA the metric or use power-of-two choices. Prefer Least Connections for variable duration; LRT only when p99 is the product metric and you can damp oscillation.
  2. "We need sticky sessions. IP hash ok?"
    Bar: No behind NAT/CGNAT — thousands of users collapse to one IP → one backend. Prefer L7 cookie affinity. If you must hash, use consistent hashing so scale-out remaps ~1/n keys, not (n−1)/n. Also: sticky fights autoscale; prefer external session store when you can.
  3. "Fleet is mixed c5.large and c5.2xlarge — Round Robin fine?"
    Bar: No — equal share saturates the small box and caps the fleet. Weighted RR or weighted least-conn with weights ∝ capacity. Better long-term: homogeneous instance types + autoscaling so weights stay trivial.

Takeaways


Re-authored and deepened for this guide. Sources: NGINX documentation, "Choosing an NGINX Plus Load-Balancing Method"; HAProxy Configuration Manual (the balance directive: roundrobin, leastconn, source, uri); AWS Elastic Load Balancing / Application Load Balancer developer guides (target groups, outlier detection, cross-zone balancing); Envoy proxy load-balancing docs (ring-hash, Maglev, least-request, power-of-two-choices); Karger et al., "Consistent Hashing and Random Trees" (STOC 1997); Alex Xu, System Design Interview, Vol. 1. Worked traces and the decision tree are original to this guide.

🤖 Don't fully get this? Learn it with Claude

Stuck on Load Balancing Algorithms? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Load Balancing Algorithms** (System Design) and want to truly understand it. Explain Load Balancing Algorithms from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Load Balancing Algorithms** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Load Balancing Algorithms** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Load Balancing Algorithms** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes