Stateless tiers behind a load balancer
Separate the routing unit, the eligible targets and the owner of session state.
Predict first
Before you read: predict
Two fresh proxies each have healthy targets A and B and round-robin selection starting at A. One is L4, the other L7 without affinity. Each receives six sequential HTTP/1.1 reads over one downstream keep-alive connection.
What are their request totals, written A:B?
The 30-second version
Horizontal scaling adds service instances behind a balancer. L4 selects a target for a connection; L7 can select per HTTP request. Keep-alive does not make those equivalent. Health checks change eligible targets. Stickiness retains a session's target while valid, concentrating busy sessions. Keep authoritative session state outside replaceable instances so reassignment does not restart progress. [S1–S4]
Separate the routing unit, the eligible targets and the owner of session state.
How it works
Step 1 of 8
Analogy: A hair salon's stations
A salon host can assign an entire appointment to one station, or assign each separate service visit at the desk. A return-to-the-same-stylist preference keeps one customer's visits together. A closed station disappears from the host's availability board, but that action does not copy its private notes. A shared service record lets the next station continue the agreed work. This is a simplified routing analogy, not guidance about hair care.
| Salon element | System meaning |
|---|---|
| Whole appointment assigned once | L4 connection target |
| Each service visit assigned at the desk | L7 request selection |
| Same-stylist preference | Session affinity |
| Station availability board | Health membership |
| Shared service record | State outside replaceable instances |
An appointment is not an HTTP stream: people can change stations mid-visit. The useful correspondence is when the host makes a routing decision. Nor does preference promise equal workloads: one customer can request many services while another requests only one. Our local request ledger makes this difference countable. [E1]
Try it
Answer first, then check. Nothing is saved.
Question 1 of 5
A catalog proxy is configured with layer=L7, sticky=true, two healthy targets, and round-robin selection for a new session. Requests arrive in this order: hot, cold, hot, hot, third, hot, fourth, hot, hot, hot.
What is the total A:B?
Question 2 of 5
Fresh proxies use layer=L4 and layer=L7 respectively. One read is sent before A fails its health check while B remains healthy; both health rounds finish.
What happens to the next read through L4, then L7?
Question 3 of 5
A proxy begins with sticky=true, only A eligible, and a session ledger containing returning → A. B then becomes eligible. It receives three reads with session returning, followed by one read each for new-one and new-two.
What are the A:B totals for the returning group, then the new group?
Question 4 of 5
A session writes cursor 9 on A, is reassigned after A is removed, then A returns before four later reads. The candidate stores its cursor in the shared cursor service and selects a healthy target for every HTTP request (sticky=false).
Which [cursor,A-count,B-count] tuple does that candidate record?
Question 5 of 5
Two sequential reads through a non-sticky L7 catalog proxy return one 503 and one 200. Both targets passed the health round that completed just before the reads.
Which defect best explains the symptom?
Go deeper
Pro tip
Log the selected target identifier alongside a request's session identifier in a synthetic test. Aggregate views can hide whether a skew follows one busy session or many connections. Keep those test identifiers separate from real user credentials or personal data. [E1]
Sources
All fetched/read 2026-09-29. S references support platform rules; E1 supplies this fixture's observations and arithmetic.
- S1: AWS, Network Load Balancer overview, TCP connection target and flow routing.
- S2: AWS, Application Load Balancer overview, per-request target selection, algorithms and content rules.
- S3: AWS, Classic Load Balancer sticky sessions, session affinity and reassignment after health failure. Fixture affinity uses an explicit test session header, not AWS cookies.
- S4: AWS Well-Architected, Make services stateless where possible, state offloading and replacement.
- S5: AWS, ALB target health checks, configured path, thresholds and all-unhealthy fail-open behavior.
- S6: AWS, NLB target-group attributes, configurable unhealthy-connection termination.
- S7: Node.js 24, HTTP Agent documentation, keep-alive sockets and request pooling. The fetched page identifies v24.21.0; the executed runtime is v24.19.0, recorded below.
- E1:
mechanisms.mjs, local HTTP/NET evidence and executed misconception variants, run 2026-09-29.
Related lessons
Checked against the tools and docs as of 2026-09-29.