Ticketmaster / BookMyShow — Detailed#
flowchart TB
subgraph Clients
WEB
MOB
end
subgraph Edge
CDN
LB
WAF[WAF + Bot filter]
QUEUE[[Virtual Queue / Waiting Room]]
end
subgraph Discover
EVT[Events Catalog]
SRCH[Search]
EVDB[(Events DB)]
end
subgraph Seat[Seat selection]
MAP[Seat Map renderer]
SEATSVC[Seat Service]
SEATDB[(Seats per show<br/>strong consistency)]
HOLD[Hold Service<br/>TTL 7-10 min]
LOCK[Redis SETNX EX lock per seat]
end
subgraph Buy
CKT[Checkout]
PAYSVC[Payment]
PG((Payment Provider))
IDEM[Idempotency keys]
SAGA([Booking saga])
end
subgraph Issue
TKT[Ticket Issuer]
QR[QR / barcode]
EMAIL[Email / SMS]
WALLET[Apple/Google Wallet]
end
subgraph Anti[Anti-abuse]
CAPTCHA
BOT[Bot scoring]
LIMIT([Per-user limits])
BLACKLIST
end
subgraph After
REFUND[Refund / cancel]
RESALE[Resale / Transfer]
SCAN([Venue scanner])
end
Clients --> CDN --> LB --> WAF --> QUEUE --> Discover
Discover --> Seat --> HOLD --> LOCK
HOLD --> Buy --> Issue
Anti --- Clients
After --- Issue
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class LIMIT client;
class WAF edge;
class EVT,SRCH,MAP,SEATSVC,HOLD,CKT,PAYSVC,IDEM,TKT,QR,EMAIL,WALLET,BOT,REFUND,RESALE service;
class EVDB,SEATDB datastore;
class LOCK cache;
class QUEUE queue;
class SAGA,SCAN compute;
class PG external;
Seat reservation correctness#
- Each seat is a unique row in
seats(show_id, seat_id, state)with state machine:available → held → sold. - Hold = atomic CAS update to
heldwithheld_until = now + TTL. - Background sweeper releases expired holds.
- Selling = CAS
held → soldonly if owner_id matches and payment captured.
Waiting room#
- High-demand events route users to a virtual queue (Cloudflare-style).
- Random fair-share lottery; users enter the buy flow in waves.
- Prevents thundering herd on seat APIs.
Anti-bot#
- Heavy captcha + behavioral fingerprinting.
- Per-account / per-IP / per-payment-method limits.
- Account age and history matter for hot drops.
Glossary & fundamentals#
Concepts referenced in this design. Each row links to its canonical page; the tag column shows whether it is a high-level (HLD) or low-level (LLD) concept.
| Tag | Concept | What it is | Page |
|---|---|---|---|
HLD |
CDN | edge caching for static assets | cdn |
HLD |
CAP / PACELC | C vs A under partition; L vs C otherwise | cap-pacelc |
HLD |
Distributed transactions | 2PC, TCC, sagas, outbox/inbox | distributed-transactions |
HLD |
Idempotency & retries | safe re-execution, backoff + jitter | idempotency-retries |
HLD |
Search internals | inverted index, BM25, embeddings, ANN | search-internals |
LLD |
State machines | FSM, HSM, transitions, guards | state-machines |
LLD |
REST API design | verbs, statuses, pagination, errors | rest-api-design |
LLD |
Behavioural patterns | Strategy, Observer, State, Command, Chain | behavioral-patterns |
LLD |
Concurrency primitives | mutex, semaphore, RW lock, atomic, CAS | concurrency-primitives |