Ticket Booking System Architecture: From API to Scalability
A ticket booking system must support event browsing, parameter-based search, and reliable reservations without double sales. Focus on data availability for reads and strict consistency for writes. Expected load—up to 10 million users for a popular event, search latency under 500 ms, read-to-write ratio of 100:1.
Key entities: Event (with date, description, type), User, Performer, Venue (with seating map), Ticket (with seat, price, status), Booking (with list of tickets and status).
Designing API Endpoints
API is built around three priority functions. Start with simple endpoints, refining as design progresses.
View event:
GET /events/:id -> Event & Venue & Performer & Ticket[]
Returns event details, venue, performer, and ticket list for rendering the seating map on the client.
Search:
GET /events/search?keyword={keyword}&start={start_date}&end={end_date}&pageSize={page_size}&page={page_number} -> Event[]
Filter by keywords, dates, pagination for high throughput.
Booking (initial version):
POST /bookings/:eventId -> bookingId
{
"ticketIds": string[],
"paymentDetails": ...
}
Later split into reservation and confirmation for transactional reliability.
High-Level Architecture
System Components
- API Gateway: routing, authentication, rate limiting, logging.
- Event Service: reading event, venue, performer data from DB.
- Search Service: handling search queries with filtering.
- Booking Service: managing reservations with transactions.
- Databases: PostgreSQL for ACID transactions (Bookings, Tickets), NoSQL or cache for reads (Events, Venues).
View flow: client → Gateway → Event Service → DB → response with seating map.
Scaling Under Load
For 10 million DAU per event, use:
- Caching: Redis for frequent reads (events, search).
- Sharding: by eventId in Tickets/Bookings.
- CQRS: separation of reads (read replicas) and writes (master).
- Load Balancer: distributing traffic across services.
100:1 read/write ratio dictates priority on read replicas and CDN for static data (seating maps).
Booking Details and Consistency
Critical area—avoiding double booking. PostgreSQL with transactions and Serializable isolation or Optimistic Concurrency Control (OCC) on ticket versions.
Process:
- Client selects ticketIds.
- Booking Service starts transaction: SELECT FOR UPDATE on Tickets.
- Check status (available), update to reserved.
- Create Booking record.
- Payment confirmation → status confirmed.
Example Tickets table:
| id | event_id | section | row | seat | price | status | version |
|----|----------|---------|-----|------|-------|--------|---------|
| 1 | 123 | A | 1 | 5 | 100 | available | 1 |
OCC: on UPDATE, check version, reject on conflict.
For high concurrency—temporary holds (TTL 10 min) in Redis.
Search Optimization
Basic SQL filtering doesn't scale to 10 million. Transition to:
- Elasticsearch for full-text search by keyword, performer, venue.
- Indexing Events with fields: name, date_range, location.
- Faceted search for filters (date, type).
Flow: Search Service → ES query → aggregation → cache in Redis.
Latency <500 ms achieved by preloading popular events.
Deep Dive into Scalability
Databases
- Master PostgreSQL (Bookings, Tickets)—sharded by eventId.
- Read Replicas—10+ for event viewing.
- Redis—sessions, temporary holds, top events.
- Elasticsearch—search, analytics.
Data migration: Event Service writes to Kafka → CDC → replicas/ES.
Monitoring and Fault Tolerance
- Circuit Breakers in services.
- Health checks, auto-scaling.
- Backups: WAL archiving to S3.
Key Takeaways
- Strict consistency only in Booking transactions, eventual consistency for search.
- OCC + temporary locks in Redis prevent 99% of conflicts without blocking.
- CQRS/ES ensure <500 ms search under 100:1 load.
- Sharding by eventId scales to 10M+ DAU.
- API Gateway centralizes security and throttling.
— Editorial Team
No comments yet.