Understand the building blocks / CHAPTER 09
Load balancing
Distribute requests across healthy capacity while preserving deadlines and safe failure behavior.
Builds on System design building blocks, Characteristics of distributed systems.
- Explain the role of a load balancer.
- Distinguish transport and application routing.
- Plan health checks, draining, and overload behavior.
01One front door, several workers
A shopper requests the product catalog. Four application servers, A through D, can all answer the request. The client uses one public address; a load balancer receives the request and chooses a server behind that address. These application servers are often called backends.
Work through capacity before choosing the routing rule:
- Tests show that each server handles 350 representative requests per second within the response-time target.
- At a peak of 900 requests per second, four servers receive about
900 / 4 = 225each under even routing. - If D is removed, three servers receive about
900 / 3 = 300each. - Compare 300 with the tested limit of 350. The survivors have some margin, provided the request mix and routing remain similar.
The balancer makes these servers usable as a pool. It cannot make a slow shared database faster or decide which shopper may claim the last item.
Two routing approaches inspect different information:
- A transport-layer balancer chooses a destination using connection information, such as addresses and ports. It need not read the HTTP request.
- An application-layer balancer can read HTTP information, such as the website name or
/catalogpath, and route accordingly. - If the balancer ends the client’s encrypted connection so it can read HTTP, that is TLS termination. TLS protects that connection; the separate connection to the application needs its own protection.
02Follow health and safe replacement
D starts successfully, but is still loading the catalog data needed to answer requests. Its process exists, yet sending shoppers to it would cause errors. Separate two checks:
- A liveness check asks whether restarting this process is likely to help.
- A readiness check asks whether this instance can handle new requests now.
For a planned replacement, the operator and routing layer follow this sequence:
- Mark D unready so the routing layer stops selecting it for new work.
- Allow time for that change to reach the routing layer.
- Let requests already running on D finish, up to a stated deadline. This is draining.
- Close remaining long-lived connections according to the reconnect policy, then stop D.
- Start the replacement. Route new requests to it only after its required data and services are ready.
A WebSocket connection cannot simply move intact to another server. The client must reconnect, and the application needs saved state from which it can resume. A session that exists only in D’s memory may disappear with D.
Health checks also have limits:
- An active check periodically probes a server. The interval creates a delay before a failure is noticed.
- Passive observations use real responses, errors, and timeouts. A healthy flag should not override repeated failed requests.
- An optional recommendation service can fail while the catalog remains useful. Marking every catalog instance unready for that optional failure can unnecessarily remove the whole pool.
Some traffic may still reach a failed instance before the routing layer reacts. Safe deadlines and retry rules remain necessary.
03State, overload, and shared limits
Suppose one shopper makes many requests. Always routing that shopper to the same server may reuse information already loaded there, but can overload that server while others are idle. This routing preference is session affinity. It does not copy session data or preserve it after a crash.
Check the complete request path:
- Measure how much work each application server is doing, rather than checking request totals alone.
- Check the shared database. If all servers wait for the same slow query, adding application servers can increase the database’s waiting queue.
- Set maximum counts for running requests and queued requests. When the queue limit is reached, reject new excess work rather than keep adding it. Remove requests that are still queued when their caller’s deadline expires; do not start work after that deadline.
- Carry the caller’s time budget through the path. From a 300 ms allowance, 100 ms already spent leaves at most 200 ms for remaining work and returning the response.
- Retry only if time remains and the operation can safely repeat. A purchase may have committed even if its response disappeared. Repeated reads also add load to an overloaded service.
The balancer is part of the required path too. One unprotected balancer process can make every healthy application server unreachable if it fails.
Test specific disruptions:
- Remove one application server at peak demand and measure the survivors’ response times.
- Replace a server while requests and long-lived connections are active.
- Start a replacement with an empty cache or unloaded data.
- Fail part of the balancer’s serving path.
- Slow the shared database and verify that waiting remains bounded.
Successful balancing means callers receive useful responses within their limits, including during the named failure. Equal request counts are only one possible means to that outcome.
A drain changes assignment before termination
Follow the numbered arrows
- 900 requests/s → Resilient balancercaller deadline accompanies work
- Resilient balancer → A, B, C surviveassign new requests
- D is draining → Resilient balancerfinish existing responses only
- A, B, C survive → Shared databasequeries can still bottleneck
Trace the diagram in words
- The routing layer stops assigning new requests to D.
- Existing work on D finishes within the drain deadline.
- The three survivors each receive about 300 requests per second, assuming even work.
- The operator checks their response times and the shared database before declaring the replacement safe.
DRAW. CALCULATE. EXPLAIN.
Plan one failure during peak
20 minutes · guided practice
Five workers each handle 250 representative requests per second within the target response time. Peak demand is 1,000 per second.
- Calculate the load after one worker fails.
- Repeat for a demand of 1,200 per second.
- Explain how to replace a worker and handle excess demand without unbounded waiting.
Compare the worked solution
- One failure leaves four workers. At 1,000 requests per second,
1000 / 4 = 250reach each worker under even routing. This is exactly the tested limit, so uneven work or retries may exceed it. - At 1,200 requests per second,
1200 / 4 = 300reach each survivor. That exceeds the tested 250-per-second capacity. - During replacement, stop new assignments before stopping the worker. Let existing work finish within a deadline and give long-lived clients a reconnect path backed by saved state.
- For the higher demand, add tested capacity or reject excess work according to policy. Limit waiting and retries; neither creates more processing capacity.
- Measure survivor response times and the shared database’s load. Even perfect application routing cannot repair a saturated database.
The checkboxes record your own assessment. The worked solution gives you a way to check the reasoning.
RETRIEVE BEFORE YOU REVEAL
Keep the important ideas.
Say the answer aloud, then turn the card over.
CARD 01What does balancing solve?
- The balancer receives a request at one public endpoint.
- It selects a ready application server.
- The server performs the operation.
The database still needs enough capacity, and a repeated write still needs its original request identifier and saved result so it does not repeat the purchase.
CARD 02What do liveness, readiness and draining each control?
- Liveness asks whether a restart would help.
- Readiness controls new request assignments.
- Draining stops new assignments and lets existing work finish within a limit.
Long-lived clients need to reconnect and recover saved state.
CARD 03How do I plan failure capacity?
- Remove the machines covered by the failure assumption.
- Divide peak demand among the survivors.
- Compare their load with tested capacity at the response-time target.
- Allow for uneven work, retries, and shared dependencies.
CHECK THE REASONING
Can you explain the choice?
Answer every question, then finish for an immediate score and an explanation for each answer. Aim for 80%, then revisit any gaps.
CLOSE THE LOOP
Explain it without the page.
Summarise the mechanism, one trade-off, and one failure mode. Then mark this chapter complete.