โ† Back to list

๐ŸŽฌ Designing BookMyShow: A Low-Level Design Deep Dive (Java)

Booking movie tickets sounds simple โ€” until you try building BookMyShow at scale. Behind every seat selection and payment confirmation liesโ€ฆ

Aditya ยท 2026-03-19 19:30 ยท 51 claps ยท 2.5 min read
#system-design-interview #low-level-design #java #bookmyshow
Open on Medium โ†—
Wiki topics: FIN ยท Fintech & Banking ๐ŸŽฌ ยท Film & Television ๐Ÿ›๏ธ ยท Politics

๐ŸŽฌ Designing BookMyShow: A Low-Level Design Deep Dive (Java)

Booking movie tickets sounds simple โ€” until you try building BookMyShow at scale. Behind every seat selection and payment confirmation lies a carefully designed system of entities, services, and workflows.

In this article, weโ€™ll break down a low-level design (LLD) of BookMyShow using a real Java implementation. Weโ€™ll explore how classes interact, how responsibilities are divided, and how core flows like booking and seat locking are handled.

๐Ÿš€ System Overview

At a high level, the system is divided into:

1. Entities (Core Models)

  • Movie
  • Theatre
  • Screen
  • Show
  • Seat
  • User
  • Booking
  • Payment

2. Enums

  • SeatStatus
  • SeatCategory
  • PaymentStatus
  • City

3. Services

  • BookingService
  • TheatreService

4. Controllers

  • BookingController
  • TheatreController

This separation follows a clean layered architecture:

Controller โ†’ Service โ†’ Entities

๐Ÿงฑ Core Domain Models

๐ŸŽฅ Movie

Represents a movie with metadata like title, duration, etc.

class Movie {
    String name;
    int duration;
}

๐Ÿข Theatre & Screen

A theatre contains multiple screens, and each screen hosts multiple shows.

class Theatre {
    List<Screen> screens;
    City city;
}
class Screen {
    List<Seat> seats;
}

๐Ÿ’บ Seat

Each seat has:

  • Category (Gold, Silver, etc.)
  • Status (Available, Booked, Locked)
class Seat {
    int seatNumber;
    SeatCategory category;
    SeatStatus status;
}

Enums improve readability and maintainability:

enum SeatStatus {
    AVAILABLE, LOCKED, BOOKED
}

๐ŸŽž๏ธ Show (Most Critical Entity)

A Show ties everything together:

  • Movie
  • Screen
  • Timing
  • Seats

The key responsibility here is seat locking:

public boolean lockSeats(List<Integer> seats) {
    // checks availability
    // marks seats as LOCKED
}

๐Ÿ’ก This is crucial to prevent double booking.

๐Ÿ‘ค User

Basic user representation:

class User {
    String name;
}

๐ŸŽŸ๏ธ Booking

Represents a confirmed ticket booking:

class Booking {
    UUID id;
    User user;
    Show show;
    List<Integer> seats;
}

๐Ÿ’ณ Payment

Handles payment state:

class Payment {
    PaymentStatus status;
}
enum PaymentStatus {
    SUCCESS, FAILED, PENDING
}

โš™๏ธ Service Layer (Business Logic)

๐Ÿง  BookingService

This is where the core logic lives.

Booking Flow:

public Booking book(User user, Show show, List<Integer> seats) {
if (!show.lockSeats(seats)) {
        throw new RuntimeException("Seat unavailable");
    }
    Payment payment = new Payment(PaymentStatus.SUCCESS);
    if (payment.getStatus() == PaymentStatus.SUCCESS) {
        Booking booking = new Booking(...);
        bookings.put(booking.getId(), booking);
        return booking;
    }
    throw new RuntimeException("Payment failed");
}

๐Ÿ” Key Observations

1. Seat Locking First

  • Prevents race conditions
  • Ensures atomicity of booking

2. Payment Simulation

  • Currently mocked
  • Can be replaced with real payment gateway

3. In-Memory Storage

Map<UUID, Booking> bookings = new HashMap<>();
  • Works for demo
  • Needs DB in production

๐Ÿข TheatreService

Handles:

  • Adding theatres
  • Mapping shows to cities

Acts as a catalog service.

๐ŸŽฎ Controller Layer

Controllers act as entry points:

BookingController

  • Accepts booking requests
  • Delegates to BookingService

TheatreController

  • Fetches shows by city/movie

โš ๏ธ Design Considerations

1. Concurrency (Very Important)

Current design:

  • lockSeats() is not thread-safe

Real-world solution:

  • Use distributed locks (Redis)
  • Or DB-level row locking

2. Seat Lock Expiry

Missing feature:

  • Locked seats should auto-release

Solution:

  • Add timeout (e.g., 5 minutes)
  • Background job to unlock seats

3. Payment Integration

Currently:

new Payment(PaymentStatus.SUCCESS);

Real-world:

  • Integrate Razorpay / Stripe
  • Handle retries, failures

4. Scalability

Current:

  • In-memory storage

Production:

  • Use DB (PostgreSQL / MongoDB)
  • Cache (Redis for seat states)

5. Search Optimization

For fast queries:

  • Index by:
  • City
  • Movie
  • Time

๐Ÿงฉ Why This Design Works

โœ… Clean Separation of Concerns

  • Entities โ†’ Data
  • Services โ†’ Logic
  • Controllers โ†’ APIs

โœ… Extensible

  • Add coupons, offers, notifications easily

โœ… Real-World Alignment

  • Mimics actual booking flow

๐Ÿง  Final Thoughts

This LLD captures the essence of BookMyShow:

  • Seat locking prevents conflicts
  • Service layer encapsulates logic
  • Entities model real-world concepts

While simplified, it forms a strong foundation for:

  • System design interviews
  • Production-grade extensions

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
post_id
ddd3f6892c40
slug
designing-bookmyshow-a-low-level-design-deep-dive-java-ddd3f6892c40
url
https://medium.com/@aditya45/designing-bookmyshow-a-low-level-design-deep-dive-java-ddd3f6892c40
canonical_url
https://medium.com/@aditya45/designing-bookmyshow-a-low-level-design-deep-dive-java-ddd3f6892c40
author_url
https://medium.com/@aditya45
status
ok
fetched_at
2026-06-21 15:33:18