Katkat

Design a Ticket Booking System for High-Demand On-Sales Without Overselling

ByteDanceSoftware Engineer · Technical Screen

Last updated

A system design question about a ticket booking system for high-demand on-sales. It probes how to absorb the traffic spike when sales open with load balancing, waiting rooms and rate limiting, and how to manage inventory with holds, payment-timeout release and consistent cache and database updates so that no ticket is ever sold twice.

Design a ticket booking system for high-demand events. Tickets go on sale at a published moment, and far more people try to buy than there are tickets. A user selects tickets, holds them while paying, and receives them once payment succeeds.

The interviewer focused on two core problems: the instantaneous traffic spike when sales open, and inventory and concurrency control, so that the same ticket can never be bought by two people. The use of a cache and a database for inventory updates under heavy concurrency was also discussed.

Constraints and Clarifications

  • Event sizes, the number of buyers, peak request rates and the payment time limit are not given. Ask for them or state your assumptions.
  • Tickets are held for a user while they pay. If payment does not complete in time, the hold must be released and the tickets returned to sale.

Clarifying Questions

  • Are tickets for assigned seats that users pick, or general-admission quantities per price tier?
  • How many tickets does a large event have, how many users try to buy at the moment sales open, and is there a per-user ticket limit?
  • How long may a user hold tickets before paying?
  • Must buyers be served in arrival order, or is any fair admission order acceptable?
  • Do bots and resellers need to be addressed?

Part 1 — Core flow and data model

Design the main components, the APIs and the data model, and walk through a purchase from opening the event page to a confirmed ticket.

What This Part Should Cover

  • Entities for events, ticket inventory, holds, orders and payments
  • APIs for viewing availability, holding tickets, paying and confirming
  • The lifecycle of a ticket from available through held to sold or released
  • Idempotency of the hold and payment steps under retries and double clicks

Part 2 — The on-sale traffic spike

At the moment sales open, a very large number of users send requests at the same time. How do you keep this burst from overwhelming the backend services and the database?

Clarifying Questions for this Part

  • Is a visible waiting room acceptable, or must every user reach the purchase page directly?
  • Is a short delay before a purchase acceptable if it makes the sale fairer?

What This Part Should Cover

  • Serving static and read-heavy content from a CDN and caches, separate from the purchase path
  • Load balancing and horizontal scaling of stateless services, prepared before a spike that lasts only seconds
  • A waiting room or queue that admits users at the rate the purchase path can sustain
  • Rate limiting per user, per IP and globally, plus graceful rejection and protection against bots

Part 3 — Inventory and concurrency control

Ensure that the same ticket can never be bought by two people. Explain how inventory is decremented, how tickets are held during payment and released when payment times out, and how you keep the cache and the database consistent so that the system never oversells under heavy concurrency.

What This Part Should Cover

  • An atomic check-and-reserve on the authoritative store, with the locking or concurrency-control choice justified
  • Holds with expiry, release on payment timeout, and the race between a late payment and an expired hold
  • The role of a cache or in-memory counter in front of the database, and how it stays reconciled with the source of truth
  • Handling of hot inventory rows under extreme contention

Hints

Hint 1

More than two states: A ticket is not simply available or sold. Think about the state in between, and about what moves a ticket into and out of it.

Hint 2

Browsing is not buying: Viewing an event and buying a ticket are very different workloads. Decide which of them needs strong consistency.

Hint 3

Most requests cannot succeed: Compare the number of buyers with the number of tickets. Decide how early in the request path you can park or turn away the users who cannot be served right now.

Hint 4

Layers in front of the database: Follow a request from the client to the inventory store, and name what each layer can absorb, slow down or reject.

Hint 5

Where the check and the decrement meet: If checking availability and decrementing it are separate steps, two buyers can both pass the check. Look for a way to make them one step.

Hint 6

Everyone wants the same row: All buyers for one event contend for the same inventory. Think about what that does to database locking, and how you could spread the load or put something in front of it.

Follow-up questions

  • A payment succeeds one second after the hold expired, and the tickets were already sold to someone else. What happens?
  • The in-memory inventory counter fails during the sale. How do you recover without overselling or permanently losing tickets?
  • How would you make admission from the waiting room fair and resistant to bots?
  • How does the design change for assigned seating, where users pick specific seats on a map?