MongoDB
Designing a Flash Sale System
Handle extreme traffic spikes for flash sales — covering pre-registration, virtual queuing, inventory atomicity, and traffic shaping.
S
srikanthtelkalapally888@gmail.com
Designing a Flash Sale System
Flash sales create massive, sudden traffic spikes — 100x normal load in seconds.
Challenges
Normal traffic: 1,000 req/sec
Flash sale: 100,000 req/sec (instant)
→ Server overload, DB overwhelmed, overselling
Pre-Registration
24 hours before sale:
Users register interest
System pre-allocates inventory slots
Send confirmation + unique token at sale time
→ Smooth demand, no surprise spike
Virtual Queue
Sale opens → All users enter queue
→ Assign position by arrival time
→ Issue entry tokens in batches
→ Show estimated wait time
→ Users enter site when their turn
Queue Position Tracker:
Redis ZADD waitlist timestamp user_id
Release N users every 5 seconds
ZPOPMIN waitlist N → Get next batch
Inventory Reservation (Atomic)
-- Lua script runs atomically in Redis
local stock = tonumber(redis.call('GET', 'stock:product_123'))
if stock <= 0 then
return 0 -- Sold out
end
redis.call('DECR', 'stock:product_123')
redis.call('HSET', 'reservations', userId, timestamp)
return 1 -- Reserved
Async write to DB after Redis reservation.
Traffic Shaping
CDN → Static pages (product details, countdown)
↓ (only when sale opens)
API Gateway (rate limit 10 req/sec per user)
↓
Queue Service
↓
Purchase Service
Architecture Layers
Layer 1: CDN — Absorb 95% of traffic (static content)
Layer 2: Queue — Serialize demand
Layer 3: Redis — Atomic inventory
Layer 4: App — Business logic
Layer 5: DB — Durable storage (async)
Post-Sale Reconciliation
Redis reservations → Verify against DB orders
Any discrepancy? → Resolve, issue refunds
Unsold reserved → Release back to inventory
Conclusion
Flash sales require traffic shaping (CDN + queuing), atomic Redis inventory, and careful reconciliation. The queue is the safety valve against catastrophic overload.