Design a Flash Sale System
A flash sale system sells a small stock of items to a huge crowd in a short window. Fairness under a rush that far exceeds the stock is the hard part.
The ask
A sale opens at a set time and a set price. Stock is fixed, and demand is far larger than stock.
An inventory reservation is a short hold that sets one item aside for one shopper while payment runs. A finished payment turns the hold into a sale.
Each shopper may buy a small set limit. The limit spreads stock across people instead of a few fast buyers.
Overselling is the failure to prevent. The system must never sell an item that is not there.
Estimate the scale
10,000,000 shoppers arrive for 100,000 items.
10,000,000 / 100,000 = 100 shoppers per item.
Half the shoppers arrive in the first 10 minutes. 10,000,000 / 2 = 5,000,000 shoppers in that window.
5,000,000 / 600 = about 8,333 arrivals per second in that window.
Most shoppers leave with nothing. The design owes them a fast, honest answer.
API and data
The operations are enter the sale, request an item, read hold status and confirm payment.
A request carries the shopper, the item and a unique request reference. A retry with the same reference returns the stored result.
Stock is a counter per item with a state per unit group. Free, held and sold are the three states that matter.
A hold record carries the shopper, the item, the count and an expiry time. An item hold lasts 5 minutes.
Payment runs outside the stock path. The stock path only holds, releases and marks sold.
High-level design
A waiting room admits shoppers in waves before the sale pages. Admission order sets a fair place in line.
Sale pages are static and served from a CDN. A page view never touches the stock service.
An app server takes item requests and passes them to the stock service. The stock service is small, guarded and scaled for the peak window.
A queue smooths requests at the stock door. Shoppers see a place and a wait instead of an error.
Payment and delivery flow after a hold succeeds. Those slower parts sit behind the hold, not in front of it.
Deep dive: the hot item counter
One hot item can take the whole rush on a single counter. A single counter cannot absorb the peak request rate alone.
The counter is split with a sharded counter design. Each shard grants holds from its slice of stock.
A shard grants a hold only when its slice still has free items. The check and the grant happen as one guarded step on that shard.
Shards report grants back for the sale view. A sold-out answer comes when every shard slice is held or sold.
A hold is a reservation against real stock, never a promise from thin air. Total holds can never pass total stock.
Deep dive: the first ten minutes
The rush is front loaded, so the design is judged by its first minutes. Pages, queues and counters are warmed before the open.
Rate limits per shopper and per network address slow scripts. A human pace passes and a machine pace is refused.
Checks that catch scripted buying run before the stock door. Hard cases go aside for review and the line keeps moving.
Sold-out state is cached and pushed fast. A clear sold-out answer ends wasted retries.
Holds that expire
A hold lasts 5 minutes while payment completes. A timer releases the item when the hold expires unpaid.
Released items return to the free pool at once. Waiting shoppers get the next chance in line order.
A payment that finishes after expiry cannot claim the item. The shopper gets a refund through a correcting payment.
Hold release is work for background workers. Expiry events ride a queue so a peak of expiries stays orderly.
Failures and retries
A crash after a grant must not lose the hold. Hold records are written to a replicated store before the shopper is told.
A shopper retry uses the same request reference. The stored result returns, and no second hold is granted.
If the stock service fails, admission pauses. Selling blind would risk overselling, and a pause is the honest answer.
After the sale, grants, holds and payments are reconciled. Any mismatch becomes a refund case for a person.
Evaluation and trade-offs
Sharding the counter buys speed and costs exact global views. The sale total settles as shard reports combine.
A waiting room buys fairness and costs excitement. Shoppers wait in line instead of racing in chaos.
Short holds free stock fast and can rush payment. Five minutes is the balance chosen for the design.
The design protects one promise above reach and speed. Stock is sold once, in line, or not at all.
Sale pressure
| Measure | Value |
|---|---|
| Shoppers | 10,000,000 |
| Items | 100,000 |
| Shoppers per item | 100 |
| First window arrivals | about 8,333 per second |
Exercise
What does an inventory reservation do?