Design Ticketmaster
Designing Ticketmaster means designing a ticket sales service that sells a fixed set of seats fairly when far more fans want them than seats exist. A big on-sale in this design brings 1,000,000 fans for 20,000 seats.
Clarify the ask
The interview question is to design Ticketmaster, a service that sells seats for events like concerts and matches.
A fan browses events and picks an event. The fan then sees the seats, chooses seats, pays, and gets a confirmation.
The service must never sell the same seat twice. A double sale is the worst failure this design can produce.
The service must also be fair. Fans who arrived earlier should get a fair chance before fans who arrived later.
Automated buyers are part of the ask. The design must slow them down without blocking real fans.
Estimate the scale
The worked on-sale brings 1,000,000 fans for 20,000 seats.
1,000,000 fans ÷ 20,000 seats = 50 fans per seat.
Most fans will leave without a seat. The design owes them a clear and honest answer, not an endless wait.
The load arrives as a burst. Tickets go on sale at one announced moment, and fans arrive within minutes of it.
Reads dominate before the sale. Fans refresh event pages and seat maps far more often than anyone buys.
Writes dominate at the moment of sale. Every purchase changes the seat record, and every change must be exact.
Name what is in and out of scope
In scope is the seat inventory. The inventory is the live record of which seats are free, set aside, or sold.
In scope is fair admission. The design controls how fast fans reach the seats when the sale opens.
In scope is the checkout boundary. The design hands a confirmed order to the payment system and records its verdict.
Out of scope is the inside of the payment system. Taking card payments is a neighbouring design, and the ticket design covers only the boundary to it.
Out of scope is how venues create events. Event staff load events and seat maps before the sale, at a calm pace.
Sketch the high-level shape
Event pages sit behind a cache and a content delivery network. Pages change rarely, so most reads never reach the app servers.
The seat inventory lives in its own store. Only the buying path writes to it, and it stays small and exact.
A controlled admission step sits in front of the buying path. It releases fans toward the seats at a pace the rest of the system can serve.
Checkout sits behind the inventory. A fan reaches checkout only with seats set aside, and checkout talks to the payment system across a clear boundary.
Inventory comes first, then admission, then the checkout boundary, then the trade-offs.
State the hard parts honestly
The first hard part is the same seat. Many fans reach for the same popular seat at the same moment.
The second hard part is the burst. A design that works for steady traffic can still collapse in the first minute of a sale.
The third hard part is fairness under pressure. Speed alone would reward automated buyers and fans with the fastest connections.
The main idea is simple. A fixed set of seats, far too many fans, and a sale that must stay exact and fair at the same time.
The deep dive starts with the inventory
Contention means many buyers trying to change the same record at the same moment. The seat inventory keeps high contention from ever selling one seat twice.
The inventory is the live record of every seat and its state.
One record exists per seat. The record names the event, the section, the row, and the seat.
The record carries a state. The state is available, held, or sold.
A held record also names the fan who holds it. It carries the moment the hold runs out as well.
The inventory stays small. A big venue holds tens of thousands of seats, and one record per seat is a modest store.
Define contention and the seat hold
Contention means many buyers trying to change the same record at the same moment. A popular seat at the opening of a sale faces the highest contention in the system.
A seat hold is a short reservation that takes a seat off sale while one fan checks out. The hold in this design lasts 10 minutes.
The hold protects the fan. Nobody can take the seat while the fan pays.
The hold also protects the seller. A fan who never pays loses the seat when the hold runs out, and the seat returns to sale.
The scale of the fight is fixed by the ask. There are 50 fans per seat, and the best seats draw far more than their share.
One record, one atomic change
A hold request asks the store to change one seat record. The change succeeds only if the record still says available.
The check and the change happen as one atomic step. Atomic means the step either happens completely or not at all, with no moment in between.
Two fans can ask at the same moment. The store orders the two requests, and only the first one sees the seat as available.
The second fan gets a clear refusal. The fan sees the seat marked as taken and picks another seat.
No lock is held across the fan's whole checkout. The state on the record does the guarding, so a crashed app server cannot guard a seat forever.
How a hold is placed and released
A fan picks seats on the seat map. The map reads from a cached copy, so it can lag a little behind the real states.
The fan confirms the pick. The buying path then asks the inventory for a hold on each picked seat, one atomic change per seat.
A group of seats succeeds together or fails together. A fan is never left holding half a row without warning.
In this worked example, fans place 500 holds a minute at the peak of a sale. 500 holds a minute × 10 minutes of hold length = 5,000 seats held at once.
A background job releases expired holds. It scans for held records past their expiry moment and sets them back to available.
A completed payment moves the record from held to sold. Sold is final, and no later step changes it.
Shard the inventory by event
The inventory is sharded by event. A shard is one part of a split store, and each event lives on one shard.
Sharding by event matches the traffic. One hot event loads its own shard and leaves quiet events untouched.
Each shard has one leader that takes its writes. The leader orders every change to its seats, which keeps the atomic step honest.
Replicas copy each shard. A replica serves seat map reads and takes over if the leader fails.
A very hot section can still overload one shard. Pacing how many fans reach the inventory at all lowers that pressure.
Where the inventory breaks
An app server can crash after placing a hold and before telling the fan. The hold simply expires, and the seat returns to sale on its own.
A leader can fail in the middle of a sale. Its replica takes over, and holds already recorded survive because they were written to the record first.
Clocks can disagree about expiry. A small safety margin on the expiry moment keeps a seat from returning while its fan is still paying.
The main idea stands. One record per seat, one atomic change per hold, and an expiry on every hold keep the inventory exact under contention.
The deep dive on admission
A waiting room is a holding area where fans wait in line before they are allowed to reach the seats. Fans leave the waiting room in a steady release, at a pace the system can serve.
Admission is the step that lets a fan through to the seats.
Without admission control, 1,000,000 fans hit the inventory in the first minutes. The inventory store can order those requests, but ordering a flood still leaves most fans with slow failures.
The waiting room changes the shape of the load. Fans wait in one ordered line, and the system releases them at a pace it can serve well.
Fairness becomes visible. A fan can see a place in line and an honest estimate of the wait.
Estimate the wait
The waiting room admits 1,000 fans per minute. That pace is a stated design choice, set to match what checkout can finish.
1,000,000 fans ÷ 1,000 fans a minute = 1,000 minutes for the last fan in line.
1,000 minutes ÷ 60 minutes an hour = about 17 hours.
1,000 fans a minute × 60 minutes = 60,000 fans admitted in an hour.
No fan will really wait 17 hours for a concert ticket. The plain line at full pace is therefore the wrong shape, and the design admits in waves instead.
After 20 minutes, 1,000 fans a minute × 20 minutes = 20,000 fans have been admitted.
After 1,000 minutes, 1,000 fans a minute × 1,000 minutes = 1,000,000 fans have been admitted.
Admit in waves
A wave is a group of fans admitted together. The system releases one wave, watches the buying path, and releases the next wave when there is room.
Only 20,000 fans can ever buy a seat. 20,000 seats ÷ 1,000 fans a minute = 20 minutes of admissions to let enough buyers through.
The first waves carry the likely buyers. Fans deep in line are told plainly that seats will probably run out before their turn.
Once the seats are sold, admission stops. The waiting room shows a sold-out message instead of releasing more fans into a hopeless checkout.
Many fans leave the line on their own. Each departure shortens the wait for everyone behind, and the line is re-estimated as it shrinks.
Keep the line fair
A fan joins the line before the sale opens or as the sale runs. The server records the joining moment, and the line follows that order.
On joining, the fan gets a pass. The pass is a server-side record of the fan's place, so refreshing the page never loses it.
A pass belongs to one signed-in account. One account holds one place, which stops a single buyer from filling the line with copies of itself.
Rate limiting guards the door of the waiting room. It slows automated buyers that try to join thousands of times.
A released fan gets a short window to start buying. A fan who misses the window returns to the line or leaves, and the place passes on.
Where admission breaks
A wave released too fast overloads checkout. The release pace therefore follows a live signal from checkout, not a fixed guess.
A fan's connection can drop inside the waiting room. The pass lives on the server, so the fan rejoins at the same place after reconnecting.
The waiting room itself can fail. Its line is stored like any other state, with replicas, so a failed server does not scatter the line.
The main idea stands. The waiting room trades a visible, ordered wait for the chaos of a flood, and it releases fans only as fast as the seats can honestly be sold.
The deep dive on checkout
The checkout seam is the boundary where the ticket design hands a held seat and a confirmed price to the payment system and waits for its verdict. Only that seam is designed, never the payment system behind it.
Checkout is the step where a fan with a seat hold pays and the sale is settled.
The seat hold lasts 10 minutes. Every part of checkout must fit inside that window, or the hold expires and the seat returns to sale.
Card payments are handled by a separate payment system. That system is a neighbouring design, and only the boundary to it is designed, with nothing behind the boundary.
A seam is a boundary where two designs meet and agree on what crosses. A clean seam lets each side change without breaking the other.
What crosses the seam
Checkout sends an order reference. The reference is one unique name for this purchase, used by both sides in every later message.
Checkout sends the list of held seats and the total price. The price was shown to the fan before payment, and it does not change across the seam.
Checkout sends an idempotency key. Idempotency means a repeated request counts once, so a retried payment request can never charge the fan twice for the same order.
The payment system answers with a verdict. The verdict is payment confirmed, payment failed, or no verdict yet.
Card details never enter the ticket service. The fan gives card details to the payment side of the seam only, so the ticket design never stores them.
Time inside the hold
In this worked example, a normal checkout takes about 2 minutes from seat pick to verdict. That figure is a stated assumption for the example.
10 minutes of hold − 2 minutes of checkout = 8 minutes of margin.
The margin absorbs slow payment answers and one careful retry. It is not spare time for extra steps, and checkout adds no optional steps inside the hold.
The fan sees the time left. A visible countdown is honest, and it stops fans from starting payment with seconds to spare.
If the hold expires before a verdict, the seat returns to sale. The order is marked expired, and the fan is told plainly and offered the chance to buy again.
Failures at the seam
A timeout is the hardest seam failure. No verdict arrived, and the payment may have succeeded or failed on the other side.
Checkout never guesses after a timeout. It asks the payment system for the status of the same order reference, and the answer settles the order.
The order moves through clear states. The states are hold placed, payment pending, paid, and released, and every move is recorded before the fan is told.
A duplicate verdict can arrive after a retry. The order reference makes it harmless, because the second verdict names an order that is already settled.
The worst case is a confirmed payment for a seat whose hold already expired and was sold again. The seam rule prevents it where possible, and where it still happens the payment side refunds the fan, a step this design only records and reports.
What stays outside the seam
Fraud checks, card storage, and bank messaging stay inside the payment system. The ticket design names none of them and depends on none of them.
The seam carries measurements both sides can see. Verdict times, timeout counts, and failure counts show whether the boundary is healthy during a sale.
The main idea stands. Checkout designs a narrow, honest boundary, one order reference, one idempotency key, and a verdict that is never guessed.
Weigh the trade-offs
Trade-offs in the Ticketmaster design are the gains and losses behind its main choices, from one strict record per seat to a paced waiting room. The main choices are weighed for what they bought and what they cost.
Trade-offs and wrap-up are the last step of the method. Each choice bought something and cost something.
The design as a whole chose exactness first. A ticket sale that is fast but wrong is worse than a sale that is a little slower and always right.
The whole design can be restated in a few lines. An interviewer should be able to repeat it back.
One strict record per seat
One record per seat, changed in one atomic step, buys certainty. A seat is available, held, or sold, and never two of those at once.
The cost is a harder fight at one point. Every buyer of a popular seat meets at the same record, and the store must order them all.
The alternative is looser bookkeeping with fixes later. That trades a rare visible refusal now for double sales and refunds later, and this design refuses that trade.
The waiting room
The waiting room buys order and protection. Fans wait in line, and the inventory and checkout only ever see a load they can serve.
The cost is a visible wait, and the wait can look absurd at full scale. At 1,000 fans a minute, the last of 1,000,000 fans would wait 1,000 minutes.
Waves soften that cost. Enough buyers for the seats are admitted early, and the rest are told honestly instead of being held in a line that cannot succeed.
Removing the waiting room would feel faster for a moment. It would then reward automated buyers and collapse checkout, which is a worse experience for real fans.
Holds and the payment seam
A 10 minute hold buys a calm checkout. The fan can pay without racing other fans for the seat.
The cost is locked seats. A held seat is off sale even when its fan has quietly walked away, until the hold expires.
A shorter hold frees seats sooner and pressures payment. A longer hold calms payment and starves the sale, and 10 minutes is the stated balance for this design.
Designing only the payment seam buys focus. The ticket design stays small and testable, and the payment system can change behind its boundary.
The cost of the seam is discipline. Every hard case, like a timeout with no verdict, must be settled by asking across the seam instead of guessing inside one side.
Wrap up the design
Ticketmaster sells a fixed set of seats to far more fans than seats. Event pages are cached, the inventory holds one strict record per seat, and a waiting room paces the buyers.
A seat hold gives one fan 10 minutes to pay. Checkout crosses one narrow seam to the payment system, with an order reference and an idempotency key.
The main idea, said once more, is exactness with fairness. The design would rather make fans wait in a visible line than sell a seat twice or let the fastest script win.
A big on-sale at a glance
| Measure | Figure |
|---|---|
| Fans arriving | 1,000,000 |
| Seats for sale | 20,000 |
| Fans per seat | 50 |
| Minutes set aside to pay | 10 minutes |
Exercise
Which choice most directly protects fairness between fans?