Backend Checks Redis Locks ticket:3 = userA (TTL left 7 min)
Final Response to User
Ticket
Final UI State
1
available β
2
booked β
3
reserved β
What Actually Happens If Redis Fails?
1. β Immediate impact:
All active locks are lost
System forgets reservations
π Result:
Multiple users may try to book same ticket
Temporary overbooking attempts
2. Why System Still Doesnβt Break Completely ?
Because: π Final consistency is enforced by database (PostgreSQL)
DB Protection:
ACID transactions
Unique constraint on ticket
Example flow:
User A β payment success β tries to book
User B β also tries
π DB ensures: Only one transaction succeeds
β One wins
β Others fail
3. User Impact (IMPORTANT β οΈ)
Users who thought they reserved β will lose it
Some users:
Complete payment β get error β
Bad experience π¬
Consistency preserved, UX degraded
4. How to Handle This (Real Systems)
β Option 1: Redis High Availability (Basic Fix)
Use Redis Cluster / Sentinel
Replication + failover
β Reduces failure chance
β Still possible edge cases
β Option 2: Graceful Degradation
When Redis is down:
Skip reservation step
Allow direct booking
π DB becomes single source of truth
β System still works
β Higher contention
β Option 3: Retry + Compensation
If payment succeeds but booking fails:
Refund automatically
Show message:
βSeat already taken, amount well be refundedβ
β Its common in real systems
5οΈβ£ Deep Dive
π₯ Deep Dive 1: Search Optimization - low-latency search
Problem:
SQL LIKE β full DB scan β
Solution:
Move Search to search optimized database βElasticsearch / AWS OpenSearch
It builds inverted index to searching document by terms really quickly
Fast text search
Supports:
text
location
filters
Example:
Event text:
Taylor Swift Live Concert Mumbai
Elasticsearch tokenizes into:
taylor
swift
live
concert
mumbai
Then maps:
swift -> [event1, event5]
concert -> [event1, event8]
...
So lookup becomes extremely fast.
Data Sync with primery data store:
Dual write (DB + ES) β
CDC (Change Data Capture) β better
CDC itself only captures database changes. We still need a consumer component, either a CDC connector or an indexing service, to transform the change event and update Elasticsearch through its indexing APIs.
Are writes frequent?
If: 100M searches/day & 100 event updates/day
Then: Kafka = probably unnecessary
If: Millions of ticketmaster events updates/day
Then: `Kafka = good idea
βIf indexing traffic becomes high, I can introduce Kafka as a buffer (temporary holding area between two systems).β
Popular Query / Hot Query search:
Cashing - CDN (fastest for common API call) e.g GET /events/search?query=taylor+swift
AWS Elastic Search has option - Node Query cashing
Redis cache - betwen search service and elastic search
Strong Interview Answer
Initially Iβd use SQL search for MVP, but for highly popular searches like Taylor Swift, full-table scans wonβt scale. Iβd move search to Elasticsearch/OpenSearch for inverted-index-based retrieval. Since search traffic is highly read-heavy and repetitive, Iβd add CDN and Redis caching to absorb spikes. Search services would scale horizontally behind a load balancer, and API Gateway would enforce rate limiting to protect the system.
π₯ Deep Dive 2: Stale Seat Map Problem
Problem
User opens event page:
10:00:00 AMGET /events/101/tickets
Response:
Seat A1 β AvailableSeat A2 β AvailableSeat A3 β Available
β οΈ What Goes Wrong?
After 2 seconds:
User B books Seat A1
Database now:
Seat A1 β Booked
But User Aβs screen still shows:
Seat A1 β Available
because the page was loaded earlier.
π Client data becomes stale.
Strong Interview Answer
The seat map can become stale because ticket availability changes frequently. To keep clients synchronized, I would establish a real-time channel using Server-Sent Events (or WebSockets). Whenever a ticket is booked or reserved, the server pushes updates to connected clients so unavailable seats are immediately disabled in the UI.
Solution 1: Polling
Every few seconds: GET /events/101/tickets
Refresh seat availability.
Problem
Too many requests
Expensive for popular events
Solution 2: Long Polling
Client sends request:
GET /events/101/updates
Server keeps connection open.
When seat changes:
Seat A1 booked
Server responds immediately.
Solution 3: SSE (Recommended π₯)
Client βββββββββ Server
Persistent connection.
Whenever ticket state changes:
Seat A1 β bookedSeat A2 β reserved
Server pushes update instantly.
No need for repeated requests.
Flow:
User books seat βBooking Service βDB updated βEvent Service βSSE push βAll connected clients
UI updates in real-time.
π₯ Deep Dive 3: Handling Taylor Swift / World Cup Ticket Rush
Problem
Normally, users open the event page and see available seats.
Seat A1 β AvailableSeat A2 β AvailableSeat A3 β Available
But for a huge event like:
Taylor Swift concert
World Cup Final
Super Bowl
Millions of users arrive at the same time.
β οΈ What Happens?
Suppose:
100,000 seats10,000,000 users
All users load the seat map simultaneously.
Initially everyone sees:
Seat A1 β AvailableSeat A2 β Available...
Then within seconds:
User1 books A1User2 books A2User3 books A3...
Real-time updates start arriving.
The seat map rapidly turns into:
A1 βA2 βA3 βA4 βA5 β...
To many users it feels like:
βI entered the page and everything instantly became unavailable.β
This creates a terrible user experience.
Strong Interview Answer
For highly popular events such as Taylor Swift concerts or World Cup finals, allowing everyone to enter the seat-selection page creates a poor experience because seats disappear instantly. Instead, I would introduce a virtual waiting queue. Users enter the queue first, and only a controlled number of users are allowed into the booking flow at a time. This protects the backend and provides a fairer and more predictable user experience.
π¨ Why Scaling More Servers Doesnβt Solve It
Many candidates say:
Let's add more servers.
But the issue isnβt server capacity.
The issue is:
Too many users competing for too few seats.
Even with infinite servers:
100,000 seats10,000,000 users
Most users will still lose.
π Solution: Virtual Waiting Queue
Note: this will be enable for only Taylor Swift/ High Traffic Events only β not for all
Instead of letting everyone enter immediately:
Users βVirtual Queue βTicket Page
Flow
Step 1
Users arrive:
10M users
Step 2
Put them into queue.
Position #1Position #2Position #3...
Store in Redis Sorted Set.
Step 3
Only allow a small batch in.
Example:
Allow first 1000 users
Step 4
When seats are booked:
1000 users leave
Next batch enters:
Next 1000 users
Benefits
Protect Backend
Instead of:
10M users βBooking Service
we get:
1000 users βBooking Service
Better User Experience
Instead of:
Everything became unavailable instantly
User sees:
You are #12,541 in queue.Estimated wait: 8 minutes.
Much more predictable.
How Queue Is Implemented
Simple answer:
Redis Sorted Set
Store:
userId -> timestamp
or
userId -> random priority
6οΈβ£ β Bad Math Good Math
Most candidates do:
DAU = 100MQPS = 10KStorage = 5TB
Then say:
βOkay, itβs a large-scale system.β
And move on.
The interviewer learns nothing.
β Bad Math
Doing calculations just because system design books told you to.
Example:
100M users1KB per event10TB storage
Thenβ¦
...
No design decision changed.
Waste of time.
β Good Math
Do math only when it affects your design.
example:
Should I shard PostgreSQL?
Now math matters.
10M events100K tickets/event
Calculate:
Total storageTotal QPS
Then conclude:
Single DB won't workNeed sharding
Now math influenced architecture.
π§ For Ticketmaster
Good places to do math:
1. Search Traffic
10M users1 search/sec
Can Elasticsearch handle it?
Need cache?
Need CDN?
2. Booking Traffic
100K seats10M users
Need waiting queue?
Answer = yes.
3. Database Size
1M events50K tickets/event
How many ticket rows?
Can one PostgreSQL instance handle it?
Need partitioning/sharding?
Paraphrased:
Donβt do back-of-the-envelope calculations at the beginning just to check a box. Do calculations when they help you make a design decision.
π₯ Interview Trick
If interviewer asks:
βAny estimations?β
Do:
Let me estimate whether a single database can handle ticket storage before deciding if I need sharding.
Thatβs much stronger than:
DAU = 100MStorage = 10TBMoving on...
π₯ Deep Dive 4: Reduce PostgreSQL Read Load
Observation
Reads >> Writes (100:1 or more)
Event, Venue, Performer data changes rarely
Strong Interview Answer
Since event metadata changes infrequently, I would cache Event, Venue, and Performer data in Redis and only hit PostgreSQL on cache misses. Ticket availability remains in the database because it changes frequently.
Cache What Cache Key?
β Event
β Venue
β Performer
β Ticket Availability (changes frequently)
event:{eventId} βEvent + Venue + Performer
Cache Invalidation
DB Update βUpdate/Invalidate Redis
Benefits
Reduces DB load
Faster response times
Handles millions of reads
7οΈβ£ π Scaling Optimizations Summary
Search Optimization
SQL LIKE β Elasticsearch/OpenSearch
Use inverted indexes
Cache popular searches using CDN/Redis
Stale Seat Map
Use SSE/WebSockets
Push seat updates in real time
Popular Event Surge
Virtual Waiting Queue
Redis Sorted Set
Controlled user entry
Read Optimization
Cache Event/Venue/Performer in Redis
Reduce PostgreSQL reads
Booking Consistency
Redis Distributed Lock (10 min TTL)
PostgreSQL transaction as final source of truth
8οΈβ£ π€ Interview Conclusion
At the end of the interview, you should quickly verify that your design satisfies both Functional Requirements and Non-Functional Requirements.
β Functional Requirements Covered
Search Events
Elasticsearch/OpenSearch
CDN/Redis caching
View Event Details
Event Service
Redis cache for Event/Venue/Performer
Book Tickets
Reserve seat using Redis Distributed Lock
Confirm booking using PostgreSQL transaction
β Non-Functional Requirements Covered
Strong Consistency
PostgreSQL transactions
No double booking
High Availability
Search and View APIs are cache-backed
Scalability
Horizontally scalable services
Virtual waiting queue for traffic spikes
Low Latency Search
Elasticsearch + CDN/Redis caching
Real-Time Updates
SSE for seat availability
Summary
We designed a Ticketmaster-like ticket booking system using a microservices architecture. Search is powered by Elasticsearch, event metadata is cached in Redis, and ticket booking uses Redis distributed locks with PostgreSQL transactions to prevent double booking. To handle large traffic spikes such as Taylor Swift concerts or World Cup finals, we introduced a virtual waiting queue and real-time seat updates via SSE. This design satisfies both the functional requirements and the scalability, consistency, and availability requirements of the system.