Ticket Booking Rules, and the Question That Changes Everything
The concrete requirements that define BookMyShow's core booking use case, plus the data-ownership decision that forces this design to solve concurrency itself.
The seat layout problem is still ahead, but physical structure is officially settled. What's left, before the harder engineering problems, is the actual use case this whole system exists for: booking a ticket.
The Booking Requirements, Laid Out Plainly
Every one of these came from asking specific, narrow questions about the booking flow rather than trying to guess the whole use case in one go, grouped by what kind of rule each one is:
Must-Have Rules
- Every booking is an advance booking.
- A booking is scoped to exactly one show. Unlike a shopping cart that can span multiple sellers, you can't mix seats from two different theatres or two different showtimes into a single transaction.
- Booking closes 30 minutes before a show starts.
- Seats have to be held during an in-progress transaction.
- Payment is online-only, handled entirely by a third party. The system itself stores nothing more than a transaction ID; every other payment detail lives on the payment provider's side.
- A cancelled show triggers a refund.
- A user can cancel their own booking for a full refund, but cancellation is all-or-nothing. There's no cancelling three seats out of a five-seat booking and keeping the rest.
Do's and Don'ts Within a Booking
- A single booking can mix seat types. Two Gold seats and one Platinum seat in the same booking is fine.
- Selected seats don't have to be consecutive.
- No seat upgrades after a booking is made.
Not Supported, For Now
- No snacks, food, or add-ons.
- No discounts or coupon codes.
The seat-holding rule above is worth sitting with for a second, because it's the first hint of the concurrency problem this whole case study eventually has to solve: two people reaching for the same seat at the same time. ("Concurrency" just means two things happening at once and possibly interfering with each other — here, two bookings racing for one seat.)
Two Quick Judgment Calls Worth Making Fast
Two smaller questions round out this list, and both are worth resolving in one sentence rather than dwelling on.
Does a QR code or invoice affect your backend design? No, both are just formatted views of data you already have.
Is a feature like search or a wallet worth mentioning even though it's not core? Yes, naming a secondary feature and correctly not building it is good triage, not a wrong answer.
The Question That Changes the Whole Design
Here's the one requirement easy to skip past, and it's bigger than everything above combined: does this system actually own the data it's showing?
For the real BookMyShow, the honest answer is no. It works closer to how MakeMyTrip works for flights: a mediator, calling into each theatre chain's own systems behind the scenes rather than owning seat data itself.
That's also why a theatre without its own booking API historically didn't show up on the platform at all, though the real product has since started partnering directly with smaller theatres too.
This is worth naming as a scoping question at the start of a real interview: "By movie booking platform, do you want an aggregator of other theatres' systems, or a real platform where I own the data myself?" It's the same scoping instinct as the very first business-objective question, just aimed at a bigger axis: not just what the system does, but who actually holds the source of truth.
Why This Design Chooses to Own the Data Anyway
For this case study, the answer is deliberate: build the platform, not the aggregator, specifically to learn how to handle seat locking and concurrency.
If BookMyShow just called into PVR's or INOX's API to reserve a seat, preventing double-booking would be their problem, not this design's. Owning the seat data means this design has to solve that concurrency problem itself, which is exactly the point of the exercise.
There's a useful pattern-recognition nugget hiding in the aggregator version of this design, even though it's not the path being taken. Picture three theatre chains, each with a completely different booking API: PVR expects a reserveSeat(showId, seatCode) call, INOX wants a single giant JSON payload, and a smaller chain only exposes an old-fashioned SOAP endpoint.
A system that has to talk to several different third-party APIs with different interfaces is a textbook case for the Adapter design pattern — a general, reusable idea, not a BookMyShow-specific trick. One adapter class per chain translates each one's quirks into the exact same reserveSeat() method your own code calls, so the rest of the system never has to know which theatre chain it's actually talking to. The same move applies any time your code needs one consistent interface over several incompatible external systems.
Two Settled Details Before the Hard Part
Fairness in a seat-booking race doesn't matter. If two people reach for the same seat at once, neither of them knows the other exists, so there's no requirement that the "right" person wins, only that exactly one of them does.
A show becomes bookable the moment it's created, with no separate waiting period layered on top of the 30-minute pre-show cutoff already covered.
Keep reading