extreme demand
Ticketmaster publicly reported that a major 2022 presale drew several billion system requests, several times its previous peak, with far more fans than seats, a case study in demand exceeding any capacity you can provision.
Design Interviews · lesson 15 of 15 · about 30 min
A ticket-booking system end to end: demand that can never be met, why a seat must be held while someone pays, how bots win a plain race, how to show a live seat map to a crowd, how a popular section overloads one partition, and what to do when a payment lands after the hold ran out. Tap any for a plain-language card.
Demand the system can never satisfy
The sizing is unusual: the total volume is tiny (50,000 sales), but the contention is enormous. What matters is how many buyers can be in checkout at once, how long each takes, and how the crowd waiting is treated. Estimate the selling time and the odds.
2 million people for 50,000 seats is 40 buyers per seat, so only 2.5% can succeed. With 2,000 checkouts at once and 4 minutes each the sale takes about 100 minutes.
2.00 million people for 50,000 seats is 40 buyers per seat: 2.5% can succeed and 1.95M cannot. With 2,000 buyers in checkout at once and 240 s each, the sale lasts about 100 minutes.
Arithmetic. Admission control (a waiting room) is what keeps the crowd from overwhelming the checkout; see the lessons on e-commerce and rate limiting.
“Sorry, that seat was just taken” at the payment screen
The hold turns a late, expensive failure into an early, cheap one, at the price of seats being locked while people dither (see the e-commerce lesson on Little's law). It also needs an atomic claim: “set held-by me if free or expired” as one conditional update. Compare how many people hit the late failure when 3,000 users chase 1,000 seats and the front rows are most wanted.
3,000 users and 1,000 seats with popularity skew 1.0 and 40 s to pay: the optimistic design makes 1,624 people fail at the payment step, about 1,080 person-minutes of wasted effort. With holds that is 0; refusals happen at selection instead.
Checking only at payment, 1,624 people reached the pay button for a seat already gone: about 1,083 person-minutes wasted. 917 seats sold.
Seeded event simulation: arrivals uniform over two minutes, seats chosen by Zipf desirability, up to four attempts per person, 2 s to try another seat, holds last 120 s.
The first thirty seconds belong to scripts
Defences are layered because none is perfect. Remove the speed advantage: a waiting room that assigns random places instead of rewarding the fastest request. Limit what one identity can do: verified accounts (phone or payment-linked), a per-account ticket cap, and per-card and per-address limits. Add bot detection (behavioural signals, device checks, ), and make the supply of accounts costly. Compare the free-for-all with a cap.
50% of requesters are bots, 20 times as fast: in a free-for-all they take 95% of the seats. If each account may buy 4 tickets and the bot operator has verified 1,000 accounts, they can hold at most 4,000 of 50,000 seats, 8%.
With 50% bots each 20× as fast, a free-for-all gives them 95% of the seats. A cap of 4 tickets per verified account, against an operator with 1,000 accounts, limits them to 4K seats, 8% of the total.
Share model: bots' share ≈ f·s ÷ (f·s + 1 − f), then limited by (accounts × cap) ÷ seats. Real bot operators also rent accounts and use residential IPs, so identity cost is the lever.
Every grey seat should turn grey as it sells
Cheaper designs decouple the two numbers. Serve the seat map as a cached snapshot (from a CDN or an in-memory store) refreshed every half second to a second, and let clients poll it or receive one batched update per interval, so cost is viewers ÷ interval whatever the sale rate. Send only the section the person is looking at, send deltas rather than the full map, and treat the map as advisory: the authoritative check happens when a seat is claimed, so a slightly stale map costs a refused click, never a double sale.
200 changes a second and 100,000 viewers: broadcasting each change is 20 million messages a second. A snapshot every 500 ms is 200,000 a second, 100 times fewer.
200 changes a second shown to 100K viewers is 20M messages a second if each change is pushed to each viewer, but 200K with a 500 ms snapshot: 100× fewer, with a seat map at most 500 ms out of date.
Arithmetic: per-change push = changes × viewers per second; batched = viewers × (1000 ÷ interval ms). The claim step stays authoritative.
Everyone wants the floor
Remedies: partition finer in the hot area (by row or by seat block rather than whole section); split a hot section's inventory into independent sub-pools that are claimed separately; keep the hottest counters in memory with an atomic operation and flush to the database; and use best available allocation (“give me any 2 together in this price tier”) which spreads demand over many seats instead of fixing it on named ones. Try the skew.
20 sections, 5,000 claims a second and partitions that can each commit 500 a second: with Zipf skew 1.0 the busiest section is asked for about 1,390 claims a second, so only 3,915 of 5,000 (78%) are served. With no skew all 5,000 are.
With 20 sections, skew 1.0 and 500 claims a second per partition, the busiest section is asked for 1.39K a second. The system serves 3.92K of 5K claims (22% lost to the hot partition).
Arithmetic: served = Σ min(section demand, partition capacity), with section demand proportional to 1 ÷ rank^skew.
Pick the mechanism
Each problem has one mechanism that fits best. Each answer is worth 20 XP.
Match the symptom: failing at the pay button, bots, update flood, or a saturated hot partition?
Customers reach the payment screen and then learn the seat was sold to someone else.
Tip: press 1 to 4 to answer, Enter for the next one.
Who lives by this
Public facts about ticketing and flash demand.
extreme demand
Ticketmaster publicly reported that a major 2022 presale drew several billion system requests, several times its previous peak, with far more fans than seats, a case study in demand exceeding any capacity you can provision.
registration before the sale
Ticketing companies introduced registration-based access, where fans sign up in advance and a subset is selected and sent codes, to take speed and anonymity out of the contest and to make bots more expensive to run.
law against circumvention
The Better Online Ticket Sales Act made it illegal in the United States to use software to circumvent a ticket seller's purchase limits or security measures, an acknowledgement that the problem needs legal as well as technical defences.
fixed-time quota opening
IRCTC opens its Tatkal quota at fixed times each day, and the rush of simultaneous bookings at those moments is a long-running example of predictable flash demand on a numbered-inventory system.
Interview angle
Six questions, each worth 20 XP. Strong answers cover fairness, holds, bots and the late-payment edge case.
Say how a seat is protected, how the crowd is admitted and how abuse is limited.
What makes ticketing different from ordinary e-commerce?
Tip: press 1 to 3 to answer, Enter for the next one.
Break it
The rules that prevent this: when a payment starts, move the seat into a “payment in progress” state that expiry does not release; set the hold a little longer than the realistic payment time (and show a countdown); on confirmation do an atomic check that the seat is still reserved for this order; if it is not, refund automatically and offer alternatives. The seat is released only when the payment fails, is cancelled, or times out with the processor.
With a 5-minute hold and a median 2-minute payment, 6.2% of payments land after the hold expires; at 50,000 payments and 30% of those seats re-sold, about 925 customers would be charged for a seat someone else has. A 10-minute hold cuts late payments to 0.3%.
6.2% of 50,000 payments (3,083) finish after a 5.0-minute hold; 30% of those seats were re-sold, so 925 customers are charged for a seat someone else owns and must be refunded.
Payment time is log-normal (sigma 0.6) around the median; late = payments slower than the hold. Re-sale share is an input, not a measurement.