Skip to main content
SDMastery
hard9 min readUpdated 2026-10-03

Design Ticket Booking: Seat Holds, Concurrency and Payments

Solve the ticket booking system design interview: seat maps, temporary holds, concurrency control, payment flow, queues, scaling, and tradeoffs.

Quick answer: Design Ticket Booking: Seat Holds, Concurrency and Payments

Design Ticket Booking: Seat Holds, Concurrency and Payments is covered here as a practical system design interview problem. Solve the ticket booking system design interview: seat maps, temporary holds, concurrency control, payment flow, queues, scaling, and tradeoffs. Use it to practice requirements, APIs, storage choices, scaling bottlenecks, data consistency, observability, and failure handling for a hard interview round.

Focus on the problem being solved, the main design choice, the failure mode, and the tradeoff you would defend in front of a senior engineer. This page is part of the DosiBridge system design knowledge graph, so it links related concepts, interview problems, tradeoffs, and references instead of leaving the topic isolated.

Diagram showing the key components and data flow in a Design a Ticket Booking System system design
High-level overview of Design a Ticket Booking System

Problem Statement

Design a ticket booking system like Ticketmaster or BookMyShow for events (concerts, movies, sports). Users browse events, view a venue seat map, select and temporarily hold seats, complete payment, and receive e-tickets. The system must handle extreme concurrency during on-sale moments when millions of users compete for limited seats.

Requirements

System architecture diagram for Design a Ticket Booking System showing how services, databases, and caches connect
System architecture for Design a Ticket Booking System

Functional

  • Browse events by category, location, and date; view venue seat maps with availability
  • Select seats: temporarily hold selected seats for 7 minutes during checkout
  • Complete booking: charge payment and issue e-tickets (QR code) atomically
  • Waiting room/queue: during high-demand events, queue users and admit in controlled batches

Non-Functional

  • Consistency: No double-booking -- a seat is sold to exactly one customer
  • Scale: 10M concurrent users during major on-sale events, 50K seat-selection attempts/second
  • Latency: Seat map loads in <1 second, seat hold confirmation in <500ms
  • Fairness: First-come-first-served with a virtual queue to prevent system overload

Core Architecture

Step-by-step diagram showing how Design a Ticket Booking System processes a request from start to finish
How Design a Ticket Booking System works step by step
  1. Seat Inventory Service -- Manages seat state per event: AVAILABLE, HELD, BOOKED. Uses Redis for real-time seat map state (hash map: seat_id -> status). Seat holds use Redis SETEX with a 7-minute TTL -- automatically released if checkout is not completed. The atomic Lua script: check seat is AVAILABLE, set to HELD with TTL, return success/failure.

  2. Virtual Waiting Room -- During high-demand on-sales, users are placed in a queue (backed by Redis sorted set with join timestamp as score). A rate controller admits N users/second to the seat selection page. Users see their position and estimated wait time. This prevents the thundering herd from overwhelming the seat inventory service.

  3. Checkout and Payment Service -- Once seats are held, the user has 7 minutes to complete payment. Flow: validate hold is still active, charge payment via Stripe/payment gateway, atomically transition seats from HELD to BOOKED in a database transaction, generate e-ticket with QR code, send confirmation email. If payment fails, seats revert to AVAILABLE (TTL expiry or explicit release).

Data flow diagram for Design a Ticket Booking System showing how requests and responses move through the system
Data flow through Design a Ticket Booking System
  1. Event Management Service -- CRUD for events, venues, and seating layouts. Venues have reusable seat map templates (e.g., "Madison Square Garden Layout A"). Events are created by linking a venue layout with pricing tiers (Section A = $200, Section B = $150). Handles event scheduling, artist info, and category tagging.

Database Choice

Redis for real-time seat availability and holds -- atomic operations (Lua scripts) prevent race conditions at 50K ops/second. TTL-based holds auto-expire without cleanup jobs. PostgreSQL for permanent booking records, user accounts, event metadata, and payment records -- ACID for the final booking transaction. Kafka for booking events consumed by email notification, analytics, and fraud detection services.

Interview preparation checklist for Design a Ticket Booking System with key points to mention and mistakes to avoid
Interview tips for Design a Ticket Booking System

Key API Endpoints

text
GET /api/v1/events/\{event_id\}/seats
  -> Returns: \{ sections: [\{ name: "A", seats: [\{ id: "A-15", status: "available", price: 200 \}] \}] \}

POST /api/v1/events/\{event_id\}/hold
  -> Body: \{ seat_ids: ["A-15", "A-16"], session_id: "S-abc" \}
  -> Returns: \{ hold_id: "H-789", expires_at: "...", seats: ["A-15", "A-16"] \}

POST /api/v1/bookings
  -> Body: \{ hold_id: "H-789", payment_method_id: "PM-1" \}
  -> Returns: \{ booking_id: "BK-456", seats: ["A-15", "A-16"], qr_code_url: "...", total: 400.00 \}

Scaling Insight

The Redis-based seat hold with TTL is the critical design choice. Using database row locks for seat holds would create massive contention during on-sale events (50K concurrent seat-selection attempts). Redis handles this with single-threaded atomic operations at 100K+ ops/second. The 7-minute TTL auto-releases abandoned holds without any background cleanup job. Combined with the virtual waiting room (which limits concurrency to a manageable 5K users simultaneously selecting seats), the system handles million-user on-sale events smoothly.

Decision guide for when to choose Design a Ticket Booking System and when alternative approaches are better
When to use Design a Ticket Booking System

Key Tradeoffs

DecisionOption AOption BChosen
Seat hold mechanismDatabase row lockRedis SETEX with TTLRedis -- 10x throughput, automatic expiry, no lock contention
On-sale traffic managementLet everyone in (hope for the best)Virtual waiting roomWaiting room -- controlled admission prevents system overload, fairer experience
Seat map renderingServer-side rendered imageClient-side SVG with data overlayClient-side SVG -- interactive, real-time status updates via WebSocket, lower server cost

Original DosiBridge notes for Design Ticket Booking: Seat Holds, Concurrency and Payments

This section is written specifically for this page, not copied from a general system-design checklist. The useful way to study Design Ticket Booking: Seat Holds, Concurrency and Payments is to connect the concept to a scarce or money-moving workflow where duplicate writes and race conditions are more dangerous than slow responses. That framing changes the design discussion from definitions to operating choices.

What makes this topic distinct

  • Core Entity: For Design Ticket Booking: Seat Holds, Concurrency and Payments, decide the core entity before choosing tools; otherwise the design looks clean but fails when ticket changes.
  • Read/Write Path: For Design Ticket Booking: Seat Holds, Concurrency and Payments, decide the read/write path before choosing tools; otherwise the design looks clean but fails when booking changes.
  • Contention Point: For Design Ticket Booking: Seat Holds, Concurrency and Payments, decide the contention point before choosing tools; otherwise the design looks clean but fails when ticket changes.
  • Abuse Path: For Design Ticket Booking: Seat Holds, Concurrency and Payments, decide the abuse path before choosing tools; otherwise the design looks clean but fails when booking changes.
  • Recovery Workflow: For Design Ticket Booking: Seat Holds, Concurrency and Payments, decide the recovery workflow before choosing tools; otherwise the design looks clean but fails when ticket changes.

Design Ticket Booking: Seat Holds, Concurrency and Payments correctness boundary

For this problem, separate the user-visible action from background work. The correctness boundary is the smallest state transition that must not be duplicated, lost, or reordered. Naming that boundary makes the solution more original than a stock API/database/cache template.

Design Ticket Booking: Seat Holds, Concurrency and Payments scaling bottleneck

The first bottleneck should be described in the language of this system: a hot timeline, a contested seat, a busy wallet ledger, a media-processing queue, or a search index update delay. That bottleneck decides which component deserves the deepest interview discussion.

Production review question

If Design Ticket Booking: Seat Holds, Concurrency and Payments suddenly receives 10x traffic, which entity becomes contested first, and what queue, lock, shard, or cache protects that entity without hiding correctness bugs?

Practical metric to track

Track ticket-booking health as a named dashboard or review item: combine one user-facing metric, one saturation metric, and one correctness metric. For Design Ticket Booking: Seat Holds, Concurrency and Payments, this keeps the discussion grounded in behavior that can be measured after deployment instead of generic advice that sounds good in an interview but never gets verified.

Sources

Unique design focus: scarce inventory and fairness under spikes

Ticket booking is not a normal ecommerce checkout because the inventory is scarce, highly contested, and time-sensitive. The main design problem is preventing oversell while keeping the experience fair when thousands of users try to reserve the same seats at the same second.

Core entities

  • Event, venue, section, row, seat.
  • Seat state: available, held, sold, blocked, released.
  • Hold: user ID, seat IDs, expiry timestamp, idempotency key.
  • Order: payment state, fulfillment state, ticket delivery state.
  • Queue position or admission token for high-demand drops.

Seat hold flow

  1. User enters a waiting room before sale starts.
  2. Admission service gives a signed token to a controlled number of users.
  3. User selects seats; inventory service attempts an atomic hold.
  4. Held seats receive a short TTL such as 5-10 minutes.
  5. Payment succeeds and converts hold to sold.
  6. Expired holds are released by a background worker.

Consistency choice

For seat ownership, strong consistency matters. Two users must not buy the same seat. This usually means a transactional database constraint, row-level locking, compare-and-set operation, or a single-writer partition for a seat group. Other parts of the system, such as email delivery, analytics, recommendations, and search indexing, can be eventually consistent.

Spike protection

  • Waiting room limits traffic before it reaches inventory.
  • Rate limits protect APIs from bots and refresh storms.
  • Signed admission tokens stop users from bypassing the queue.
  • Idempotency keys prevent duplicate orders during retries.
  • Seat maps can be cached, but seat state must refresh or stream updates.

Failure handling

If payment succeeds but ticket fulfillment fails, the order should remain paid and retry fulfillment. If payment times out, the hold should remain until expiry or confirmed failure. If the user refreshes checkout, the idempotency key should return the existing order or hold instead of creating a duplicate.

Interview tradeoff

The strongest answer separates scarce-seat consistency from the rest of the architecture. Use strict correctness for the final seat transition, but use queues, caching, and eventual processing for everything that does not decide who owns the seat.