Requirements
- Users can browse events, select seats from a seat map, reserve seats, and complete payment
- Prevent double-booking: no two users can book the same seat for the same event
- Handle demand spikes: popular events (Taylor Swift, Super Bowl) have tens of thousands of simultaneous buyers
- Seat holds expire after 10 minutes if payment is not completed
Data Model
Event(event_id, venue_id, name, date, status ENUM(ONSALE,SOLDOUT,CANCELLED))
Venue(venue_id, name, total_capacity, seat_map_json)
Seat(seat_id, venue_id, section, row, number, category ENUM(GA,FLOOR,BALCONY))
SeatInventory(seat_id, event_id, status ENUM(AVAILABLE,HELD,SOLD), held_by, held_until)
Order(order_id, user_id, event_id, status ENUM(PENDING,CONFIRMED,EXPIRED,CANCELLED),
created_at, expires_at, total_amount)
OrderItem(item_id, order_id, seat_id, price)
Seat Reservation Flow
- User selects seats on the seat map
- POST /orders/hold: BEGIN TRANSACTION; SELECT * FROM SeatInventory WHERE seat_id IN (…) AND event_id=X FOR UPDATE; verify all are AVAILABLE; UPDATE SeatInventory SET status=’HELD’, held_by=user_id, held_until=NOW()+10min; create Order (PENDING, expires_at=+10min); COMMIT
- User completes payment within 10 minutes
- POST /orders/{id}/confirm: BEGIN TRANSACTION; verify Order status=PENDING and not expired; charge payment; UPDATE SeatInventory SET status=’SOLD’; UPDATE Order SET status=’CONFIRMED’; COMMIT
The SELECT FOR UPDATE serializes concurrent seat selections. If two users try to hold the same seat, one gets the lock and succeeds; the other finds status=’HELD’ and fails with SeatUnavailable error.
Hold Expiry
A background job runs every 30 seconds: SELECT * FROM SeatInventory WHERE status=’HELD’ AND held_until < NOW(). For each expired hold: UPDATE SeatInventory SET status=’AVAILABLE’, held_by=NULL, held_until=NULL WHERE status=’HELD’ AND seat_id=X (compare-and-swap to avoid racing with a concurrent payment confirmation). UPDATE Order SET status=’EXPIRED’. Notify the next user in the queue (if waitlist exists).
High-Demand Sale Architecture
- Virtual queue: before sale opens, users join a queue. At sale time, release users in batches (e.g., 1000 every 30 seconds). Each released user gets a signed purchase token (JWT) valid for 10 minutes. Only token holders can enter the purchase flow.
- Rate limiting: max 1 queue entry per user per event. Redis SET nx per user+event.
- CDN: event listing page and seat map SVG served from CDN — no origin hit until seat selection
- Read replicas: seat availability queries go to read replica; writes go to primary
- Seat map cache: cache seat availability bitmap in Redis (bitset per event, bit per seat), updated on each reservation. Display uses cached bitmap; actual booking uses DB.
Seat Map Availability at Scale
Fetching all 50,000 seats’ status per page load from DB would be too slow. Use a Redis bitset: key=availability:{event_id}, one bit per seat_id. Bit=1 means available. SETBIT on reserve, GETBIT on display. The bitmap for a 50,000-seat venue is only 6KB. Cache with TTL=5s; slight staleness is acceptable for display (actual booking still validates in DB). Serve the bitmap to clients; render the seat map in JavaScript.
APIs
GET /events/{id}/seats → seat availability bitmap
POST /orders/hold → {event_id, seat_ids[]} → Order
POST /orders/{id}/confirm → {payment_token} → Order (CONFIRMED)
DELETE /orders/{id} → cancel hold, release seats
GET /orders/{id} → Order status
Key Design Decisions
- SELECT FOR UPDATE on SeatInventory rows prevents double-booking without application-level locking
- 10-minute hold + expiry job ensures inventory is not held hostage by abandoned sessions
- Virtual queue absorbs the spike; DB sees metered traffic, not a stampede
- Redis bitset for display, DB for authoritative booking
Airbnb system design covers reservation and availability systems. See common questions for Airbnb interview: reservation and booking system design.
Stripe system design interviews cover payment flows and atomic reservations. See patterns for Stripe interview: payment and seat reservation system design.
Amazon system design covers high-demand reservation systems. Review design patterns for Amazon interview: ticketing and reservation system design.