๐ฌ 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โฆ
๐ฌ 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)
MovieTheatreScreenShowSeatUserBookingPayment
2. Enums
SeatStatusSeatCategoryPaymentStatusCity
3. Services
BookingServiceTheatreService
4. Controllers
BookingControllerTheatreController
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