600,000 people for 48,000 seats
A stadium tour adds one more date, and its 48,000 seats go on sale at 10:00 on a Saturday. Fans may buy up to four, and orders average three, so the date sells out in about 16,000 orders. By 9:59 some 600,000 people have the event page open. The page is the same for everyone, and a CDN can serve it to all of them. The checkout behind it cannot: picking seats reads live availability, holding them writes to the inventory, paying calls an outside provider, and load tests say the whole path completes about 2,000 orders a minute before it slows down.
At that pace the seats last about eight minutes, and most of the 600,000 leave without tickets whatever the design does. The design decides two other things: whether the checkout is still working after the first minute, and which 16,000 or so orders get through.
What a refusal rewards
Without anything in front, the checkout takes what it can at 10:00 and the rest get errors. A person who gets an error presses Buy again, a script presses it forty times a second, and every retry is another draw: the seats go to whoever retries hardest, and the retries hold the load at its peak long after the first second. A per-client cap slows the script down but puts nobody in order; that cap is the subject of Rate limiting.
Refusing the excess is the usual answer to an overload nobody planned for (Load Shedding, and Backpressure & load shedding for overload as a whole). A crowd that was told the time weeks ago is different: refused fans come back harder, so refusal hands the seats to the fastest retrier. Diagnose: On-Sale Rush Hits the Booking Store starts from a design with nothing between this crowd and the database that also commits purchases.
A line outside the checkout
The fix is to replace the lottery with a line, held in front of the site: a virtual waiting room. Every request for the on-sale's protected pages (the seat map, the holds, the payment) reaches the room first. A browser without permission to go further gets a holding page with its place in line, and the page asks the room for news every 20 seconds or so. The room lets people out from the front at a controlled pace, so the checkout sees a steady flow instead of 600,000 at once. No request is held open while people wait: the line is a list of sessions and positions in a fast store, and each poll is a cheap read, though 600,000 people polling every 20 seconds still make about 30,000 of them a second.
This looks like Queue-Based Load Leveling, and the difference is what is in the queue. That pattern queues messages, work someone already submitted, for a worker to drain at its own pace. The room queues people before any work exists: nobody in line has picked a seat yet, because which seats are worth picking depends on what is left when they get in.
Every on-sale request reaches the waiting room first. It keeps the line in a fast store and lets people through to the order service at the pace the checkout can finish, each with a signed admission token.
How fast the door opens
The pace comes from what the checkout can finish, not from what the room can serve: letting people through as fast as the room answers polls would only move the crowd one step inward. Choosing seats, typing card details and confirming takes about four minutes, so a checkout running at 2,000 orders a minute has around 8,000 people inside it at once (on average, in a steady state: arrivals per minute times minutes inside). Rather than fix a rate, the room can count active sessions, people admitted who have not yet paid, left or timed out, and let the next person in whenever one ends while the count is under 8,000, a starting figure for a load test to confirm. A closed tab frees its place when the session expires after ten idle minutes. If payment slows and visits stretch to six minutes, places free up more slowly and admission slows with them, without anyone recalculating a rate. Letting the downstream's state set the pace upstream is back-pressure, the pattern Back-Pressure describes in general.
Admission decides who may try, not who gets a seat. Two of the 8,000 can still click seat 14 in row F in the same second, and the inventory decides between them with a conditional write, explained in Transactions & isolation levels.
A pass bound to one session
A line only works if the checkout refuses people who skipped it, such as a script that goes straight to the seat map's URL. So a fan who reaches the front gets an admission token from the room: which session was admitted, for which on-sale, until when, signed so the checkout can verify it without calling the room. The order service, or a gate in front of it, checks it on every protected request and sends anyone without a valid one back to the line. While the session is active the token is renewed, so it lapses only after ten idle minutes; when the order is done, the order service marks that session finished and refuses its token from then on. Either way, a finished order or a lapsed token, the session leaves the room's count and the next person in line takes its place.
Because the token expires in minutes and the checkout refuses it from any session but the one it names, one admission posted to a forum does not let a thousand people in. Copying the session cookie along with it still works, so the binding raises the cost of sharing rather than ending it.
Who stands at the front
The order people leave the room in is the fairness policy, and there are two common ones. First come, first served ranks people by when they joined. It suits a sale where arrivals spread over hours. For one that opens at 10:00 sharp it rewards who clicked within a few milliseconds of 10:00:00, on the fastest connection, or with a script timed to the moment.
So some on-sales open the room early, say at 9:30, and at 10:00 give everyone already inside a random position. Arriving at 9:31 or at 9:59 makes no difference, which removes the reason to hammer the page in the last second, and people who arrive after 10:00 queue behind that group in arrival order. The draw is fair per session, not per person, and that is its weak point: someone who opens 30 browsers holds 30 entries. What helps is tying a place to something harder to multiply than a browser: a signed-in account with one place in line, a bot check on joining (at the edge, see Edge protection: WAF, DDoS & defence in depth), and the purchase limit at checkout. None is complete alone; together they make extra places cost more to get.
An honest number on the holding page
The holding page shows the position, and the room can turn it into an estimate from what it measures: position 41,200, with the line moving about 2,000 a minute, is roughly 20 minutes away. The rate changes, so the estimate moves both ways: payment slowing down stretches it, people ahead giving up shortens it.
The position also says something about the seats. About 16,000 orders empty the inventory; the room will let in more people than that, since some leave without buying, and how far down the line the seats reach depends on how many do. When what the room measures puts position 41,200 out of reach, saying so lets people that far back decide whether to keep waiting. When every seat is sold or held by someone at checkout, the room stops admitting; holds that expire put seats back, and the room resumes. Once the seats are sold, it tells everyone still in line, instead of letting them reach the front and find an empty seat map.
The room in the Event Ticketing Challenge
The Event Ticketing Challenge asks you to "Queue users fairly during high-demand on-sales", and its guided build wants a waiting-room layer in front of the booking service. Place a Rate Limiter between the storefront and the order service, on every on-sale path. A bare limiter only refuses, the retry lottery from the start, so write on its edges what makes it a room: on the way in, the position and the fairness policy you chose; on the way out, the admission token and the pace, worked out from your own estimate of what the checkout can finish. Then answer the guided hint about whether people queue before or after they see the seat map: this article put them in line before it, because picking seats reads live availability, and your answer rests on what serving your map costs.