System Design
Ticketmaster — High-Level Design
A walkthrough of how I'd design an event-booking platform like Ticketmaster, BookMyShow, or District — from a single server to microservices, a CDC-backed search index, Redis seat locks, and a waiting queue for sold-out on-sales. Below is the design, step by step.
- 01
Requirements, API & Day 0
Functional needs are search, view event details, and book. Non-functional ones matter more here: strong consistency so the same seat is never sold twice, reads far outnumber writes, and the system must absorb search surges when a popular event drops. Day 0 is a single server and one Postgres — events, venues, and tickets in three tables. Fine to start; it will not survive a Taylor Swift on-sale.

- 02
Day 100 — Microservices
Split behind an API Gateway: a Search service, an Event CRUD service (create/update events and seats), and a Booking service (tickets + payments). All three still share one database. Postgres can answer search queries, but it is not built for fuzzy, geo, and faceted search at read-heavy scale — that is where Elasticsearch / OpenSearch comes in.

- 03
Search Index via CDC
Search reads from Elasticsearch; Event CRUD and Booking write to Postgres as the source of truth. Changes flow out through CDC: Postgres WAL → Debezium → Kafka → Elasticsearch. Writes stay strongly consistent; search is eventually consistent — the right trade-off when read RPS dwarfs writes.

- 04
Read Path vs Write Path
Users hit the gateway, then either Search (Elasticsearch) or Event CRUD / Booking (Postgres). CDC keeps the index in sync so the search cluster never talks to the transactional store. With that split in place, the remaining hard problem is the booking flow itself.

- 05
Reserving a Seat — Redis TTL
POST /reserve must lock a ticket so two users cannot hold the same seat. A DB status column plus a cron to expire 10-minute-old holds works, but it is slow and easy to get wrong. Redis is a better lock: SET the ticket key with a 10-minute TTL. Confirm via Stripe / Razorpay webhooks — not the frontend — then delete the key and persist the booking. If payment never lands, the key expires and the seat is free again.

- 06
Booking Service + Payments
Booking now talks to three things: Postgres (source of truth), Redis (short-lived seat locks), and Stripe / Razorpay (charges). Webhooks confirm payment server-to-server, so a closed tab or dropped network cannot leave a seat stuck in limbo.

- 07
Waiting Queue for Mega Events
A Taylor Swift or Arijit Singh on-sale will melt the booking service if everyone hits /reserve at once. Users POST /join, get a per-user token (so a shared URL cannot skip the line), and the frontend polls admission. An admission service lets the next person in only when a slot frees — e.g. capacity 100, user 35 finishes, user 101 enters.

- 08
Final Architecture
The full picture: Search → Elasticsearch, Event CRUD → Postgres, Booking behind a Kafka waiting queue with Redis locks and payment webhooks. CDC (WAL → Debezium → Kafka → ES) keeps search fresh. Reads scale independently; writes stay consistent; the queue absorbs the on-sale spike.
