Skip to main content

Preview — Pro guide

You are seeing a portion of this guide. Sign in and upgrade to unlock the full article, quizzes, and interview answers.

Movie & Event Ticket Booking — LLD (Seat Map, Holds, Concurrency)

Object-oriented design for BookMyShow-style ticketing: venue seat graph, per-show instance inventory, time-boxed seat holds, and TOCTOU-safe booking. Covers pricing strategies, idempotent checkout, and extension to best-available search without an HLD detour.

55 min read 3 sections 1 interview questions
Movie Event TicketingBookMyShowSeat Map ModelingShowInventoryHold TimeoutOptimistic LockingTOCTOUStrategy PatternObject-Oriented DesignInventory ReservationIdempotencyInterview LLDSEDIE Framework
IMPORTANT

What Interviewers Are Actually Testing

This problem is inventory reservation under contention, not drawing Seat rectangles on a whiteboard. Strong candidates separate three clocks: the show (a performance instance in time), the seat (a durable asset in a venue), and the hold (a short-lived lease so payment can run). The trap is implementing is_seat_free() and book() as two steps without an atomic path — the same race you fix in hotel booking, but with explicit seat labels and a visible UX countdown. A staff-level answer names at-least-once payment webhooks, idempotent booking confirmation, and why best-available search belongs behind a pluggable SeatSelectionStrategy interface.

Clarifying Questions — Before You Draw a Seat Grid

01

Fixed seating (each seat is unique) vs general admission?

Fixed seating: each Seat has row/column, state is per (show, seat_id). General admission: model CapacityBucket and decrement a counter; selection strategy collapses to FIFO. Most interviews mean fixed — confirm early.

02

Single venue or many screens under one tenant?

Single Venue is enough for the core LLD. Multi-venue chains add a CinemaChain root and venue-scoped inventory; out-of-band search is deferred but name it.

03

How are prices determined?

Flat per seat, per section (Orchestra, Balcony), or dynamic (surge by demand). Drives a PricingEngine and SeatingSection with its own Money base price — not a get_price() on Seat.

04

Hold duration and what happens on expiry?

Typical: ~5–10 minutes on the client timer (exact seconds are a product choice). Hold transitions EXPIRED and releases the seat; background sweeper reclaims lost holds. Ask whether partial payment retries are in scope (usually: idempotent confirm endpoint).

05

Pick-your-seat vs best-available auto assignment?

Pick-a-seat: user selects specific seat_id values. Best-available: BestAvailableSelector returns the first k non-overlapping seats per policy (adjacent, center bias). This must be a Strategy — the graph layout algorithm should not be hardcoded in BookingService.

06

Concurrent requests per show scale?

If millions fight for a stadium onsale, the LLD object model stays the same; the interviewer may expect you to name DB SELECT ... FOR UPDATE on (show_id, seat_id) or optimistic retries. Say it explicitly even if the code uses one lock.

IMPORTANT

Premium content locked

This guide is premium content. Upgrade to Pro to unlock the full guide, quizzes, and interview Q&A.