Design a Ticket Booking System
Practice a ticket-booking design with inventory holds, concurrent purchases, payment confirmation, expiration, fairness, and oversell prevention.
What you'll learn
Run the architecture drill
- How to model inventory, short-lived holds, orders, and confirmed tickets separately.
- Why oversell prevention needs an authoritative concurrency boundary.
- How payment uncertainty and hold expiration interact in a realistic booking flow.
A ticket booking system is a concurrency and correctness problem disguised as a shopping flow. Its central challenge is giving users a fair reservation experience while preventing two buyers from successfully purchasing the same scarce inventory during traffic spikes, payment uncertainty, and hold expiration.
Start with the architecture drill, then follow the request path through scale, failure, and a defensible interview answer.
Make your assumptions and decision path easy to inspect.
ATOFF architecture reasoning canvas
Design a Ticket Booking System: the architecture drill
Short answer
A ticket booking system protects scarce inventory with one authoritative allocation decision, bounded holds, and a payment-finalization flow that cannot oversell.
10× evolution
Introduce a waiting room and partition allocation without splitting a seat's authority.
01 Decision checkpoint
Design brief
Allocate a seat through conditional state transition or serialized ownership so no two successful orders can claim the same unit.
02 Decision checkpoint
First request path
A hold needs an expiry, owner, and visible countdown; releasing it must be idempotent because expiry and payment callbacks race.
03 Decision checkpoint
Failure drill
Treat payment confirmation as an event that attempts to convert a still-valid hold, then reconcile late or uncertain outcomes without selling twice.
Say it in the interview
I would state the no-oversell invariant, use expiring holds for fairness, and make payment confirmation a conditional finalization rather than a blind update.
- 1
Buyer
browse: Availability view · request hold: Inventory command conditional update
- 2
Availability view
- 3
Inventory command conditional update
reserve if available: Expiring seat hold
- 4
Expiring seat hold
hold ID + deadline: Idempotent payment attempt · deadline: Hold expiry worker
- 5
Idempotent payment attempt
successful outcome: Confirm transaction order + ticket
- 6
Confirm transaction order + ticket
sell once: Confirmed ticket
- 7
Confirmed ticket
- 8
Hold expiry worker
release if unconfirmed: Inventory command conditional update
- Buyer flows to Availability view via browse.
- Buyer flows to Inventory command conditional update via request hold.
- Inventory command conditional update flows to Expiring seat hold via reserve if available.
- Expiring seat hold flows to Idempotent payment attempt via hold ID + deadline.
- Idempotent payment attempt flows to Confirm transaction order + ticket via successful outcome.
- Confirm transaction order + ticket flows to Confirmed ticket via sell once.
- Expiring seat hold flows to Hold expiry worker via deadline.
- Hold expiry worker flows to Inventory command conditional update via release if unconfirmed.
Walk the design under pressure
Model scarce inventory and reservation state explicitly
Clarify whether the system sells assigned seats, interchangeable capacity, timed entry, or a waitlist. A seat map needs per-seat state, while general admission may use a bounded count. In either model, distinguish available, held, sold, released, and expired states so the customer experience maps to durable evidence.
A hold is not a purchase. Give it an owner, expiry, and stable ID. It should reserve inventory through an authoritative transaction or concurrency mechanism rather than relying on a cache value that several buyers can read simultaneously.
Prevent oversell at the inventory boundary
For assigned seats, a conditional update or transactional lock can change a seat from available to held only if its version and state still match. For a quantity, an atomic decrement guarded by remaining capacity can reserve one unit. The exact primitive depends on the data store, but the invariant is the same: only one successful state transition consumes the last unit.
Avoid holding a long transaction open during user payment entry. Record the short inventory hold, then process payment independently with a deadline. This reduces lock contention while keeping the final confirmation tied to authoritative inventory state.
Resolve the race between payment and hold expiry
A payment can be accepted just as a hold expires. Define a deterministic policy: extend the hold while an authorized payment is in flight, attempt final confirmation before expiry, or place the order in reconciliation if evidence is uncertain. Never simply charge first and hope inventory remains.
Expiration must be processed safely even if a worker runs late. Treat it as a state transition with version checks, and make a confirmed order immune to a stale expiry worker. Audit every transition so disputes can be investigated from facts.
Staff-level insight: fairness and surge controls are product requirements
At staff scope, traffic spikes during an on-sale event need queueing, admission control, bot mitigation, tenant/event isolation, and transparent user feedback. A virtual waiting room can protect the booking system, but it must have a fairness policy and should not become an opaque bypass mechanism.
In an interview, describe the failure path: inventory service unavailable, payment pending, client retry, and final reconciliation. The strongest answers preserve the invariant, communicate uncertainty honestly, and avoid claiming a distributed workflow is magically atomic.
Keep this with you
Key takeaways
- Scarce inventory needs authoritative conditional state transitions to prevent oversell.
- Holds, payment attempts, and confirmed tickets are separate records with separate lifecycles.
- Expiry, retries, fairness, and reconciliation are central to a credible booking design.
Practice aloud
Interview questions to explore
- 1.How do two buyers trying to reserve the last seat converge on one result?
- 2.What happens if payment is accepted after a hold technically expired?
- 3.How do you protect the system during an on-sale traffic surge?
Common follow-ups
Frequently asked questions
Why not reserve a seat only after payment succeeds?
Payment itself can be slow or uncertain. A short, durable hold gives the buyer a fair window while preserving a clear inventory boundary; the final booking still requires authoritative confirmation.
Can a cache manage ticket availability?
A cache can speed seat-map reads, but it should not be the only authority for a scarce-item state transition because stale or concurrent values can cause overselling.
Already an Elite member? Open the complete walkthrough.
Need the broader preparation context? Go back to Interview Preparation for behavioral readiness, question practice, and the larger AceTheOffer preparation framework.