About Us Contact Us Write for Us Advertise
Home > System Design > Low-Level Design > Design BookMyShow / Movie Booking (Low-Level Design)
System Design › Low-Level Design

Design BookMyShow / Movie Booking (Low-Level Design)

Design a movie ticket booking system in an LLD interview — the concurrency-focused version. Modelling Movie/Show/ShowSeat, and the reserve-then-confirm seat locking that prevents double-booking. Classes, UML, decisions.

Shiv Pandey
Shiv Pandey
Oct 26, 2026 | 1 views
Design BookMyShow / Movie Booking (Low-Level Design)

🔴 Low-Level Design · Case Study · Super-senior (concurrency)

"Design BookMyShow / a movie ticket booking system" as a low-level design question is really about one hard thing: two users must never book the same seat. The class model is straightforward; the concurrency is what separates a good answer from a great one. (For the distributed-scale version, see the HLD Ticketmaster design — here we focus on the objects and locking.)

The approach in one line: model Movies → Shows → Seats, and make seat booking a reserve-then-confirm flow guarded by locking, so a seat moves AVAILABLE → LOCKED (briefly, per user) → BOOKED and can never be sold twice.

Step 1 — Requirements

  • Functional: browse movies and their shows across theaters; view a show's seat map; select and book seats; pay; get a booking confirmation.
  • Non-functional (the point): no double-booking under concurrent users, correct seat state, graceful handling when a seat is taken while you're choosing.

Step 2 — The classes

  • Movie — a film; shown as many Shows.
  • Theater → Screen — a theater has screens; a screen has physical seats.
  • Show — a movie on a screen at a time; owns the bookable ShowSeats (seat + status for this show).
  • Seat / ShowSeat — a seat's status (AVAILABLE / LOCKED / BOOKED) is per-show, not per-seat.
  • Booking — a user + a set of ShowSeats + status; Payment confirms it.
Movie Theater→Screen Show ShowSeat(status) Booking 1..* seats booked in

Step 3 — The core: preventing double-booking

🔴 Naive "check available → mark booked" has a race: two users both see a seat free and both book it. The fix is the reserve-then-confirm pattern with a lock:

  1. User selects seats → the system tries to LOCK them (a temporary hold, e.g. 5 minutes). This must be atomic — only one user can win the lock on a seat.
  2. Locked seats show as unavailable to others. User pays within the window → seats become BOOKED.
  3. If the timer expires or payment fails → the lock releases and seats return to AVAILABLE.
class Show {
    private final Map<String, ShowSeat> seats;
    // atomic lock: synchronized (or a per-seat lock / DB row lock)
    public synchronized boolean lockSeats(List<String> ids, User u) {
        for (String id : ids)
            if (seats.get(id).status != AVAILABLE) return false;   // someone took it
        for (String id : ids) { seats.get(id).status = LOCKED;
                                seats.get(id).lockedBy = u;
                                seats.get(id).lockExpiry = now()+5min; }
        return true;   // this user won all seats
    }
}

The check-and-lock happens as one atomic step (a synchronized block here; in a real system a DB transaction with row locks / SELECT … FOR UPDATE, or a distributed lock). That atomicity is the entire answer to "how do you prevent double-booking?"

Step 4 — The seat-lock design decisions

🔴 What interviewers dig into:

  • Pessimistic vs optimistic: pessimistic locking (lock the seat rows) suits high contention (a blockbuster on sale); optimistic (version check at commit) suits low contention. Name both.
  • Lock expiry: a background sweeper releases expired locks so abandoned carts don't hold seats forever.
  • Idempotent payment: the confirm step must not double-charge on retry (link to payment design).

Step 5 — Other structure

🟠 Search (movies by city/date) is a lookup over the movie/show data. Booking is itself a small state machine (CREATED → CONFIRMED → CANCELLED). Keep seat status per show, not per physical seat, since the same seat is independently bookable across shows.

The interview-ready walkthrough

"I'd model Movie → Show → ShowSeat (seat status is per-show) with Booking and Payment. The core is preventing double-booking, so I use reserve-then-confirm: selecting seats atomically locks them for a few minutes (AVAILABLE→LOCKED→BOOKED), releasing on timeout or failure. The check-and-lock is a single atomic step — a synchronized block or, realistically, a DB transaction with row locks (pessimistic for hot shows, optimistic otherwise). A sweeper frees expired locks, and payment is idempotent." That puts the concurrency front and centre — exactly the crux."

What to read next

← Design a vending machine · Design Splitwise →

Related Articles

Design a Vending Machine (Low-Level Design)
System Design › Low-Level Design

Design a Vending Machine (Low-Level Design)

Design an Elevator System (Low-Level Design)
System Design › Low-Level Design

Design an Elevator System (Low-Level Design)

Design a Parking Lot (Low-Level Design / OOD)
System Design › Low-Level Design

Design a Parking Lot (Low-Level Design / OOD)

How to Approach a Low-Level Design (LLD) Interview: The Framework
System Design › Low-Level Design

How to Approach a Low-Level Design (LLD) Interview: The Framework