Classic design · Senior
Flash sale
Classic interview design. Key points: reservations and concurrency, and overload control.
Short answer
Classic interview design. Key points: reservations and concurrency, and overload control. The flash sale isolates one hard piece of e-commerce: selling a very limited quantity of stock under extreme demand. The goal is to let buyers compete fairly for the units and complete the purchase without ever selling beyond the stock.
01 · CONTEXT
Few units, many people
The flash sale isolates one hard piece of e-commerce: selling a very limited quantity of stock under extreme demand. The goal is to let buyers compete fairly for the units and complete the purchase without ever selling beyond the stock.
The flow gains a step between viewing the product and paying: reserving the unit. Payment goes through a third party and takes seconds, and stock cannot be held in an open database transaction for all that time. The reservation takes the unit out of circulation immediately and leaves the settling of the money for later.
The public material lists four deep dives that form the roadmap of this case: maintaining consistency under extreme contention, efficiently releasing expired reservations, handling millions of users arriving at once, and making access to limited stock fair.
02 · RACE
The counter that goes negative
The naive way to sell is to read the available count, check that it is greater than zero, and then decrement it. For a single buyer this is correct. With two buyers at the same instant, both read the same count, both conclude there is a unit to sell, and both proceed to charge the card.
When the two writes arrive, the first takes the count to zero and the second decrements again, and the count goes negative. The seller ends up with a refund to issue and two unhappy customers.
Two buyers request the last unit almost at the same instant.
Both requests read the same count and see one unit available.
Each concludes there is a unit to sell and proceeds to the charge.
The first write takes the count to zero and the second decrements again, leaving it negative.
A single count row forces every checkout of the item to update the same row, which sets up the next section.
03 · HOT ROW
One row, one queue
In Hello Interview's description of the Shopify work, the obvious attempt in a relational database was one row per item with a quantity counter. Every checkout of a popular item had to update the same row, and InnoDB, MySQL's engine, grants the row lock to one transaction at a time, so the other buyers wait. Thousands of checkouts of the same item collapsed into a single lock.
The documented way out spreads the contention. To reserve units, the system selects and locks available rows and removes them from the pool. The SKIP LOCKED feature makes MySQL skip locked rows and look for another available one; this way, two buyers of the same item lock different rows and commit in parallel, instead of waiting behind a shared counter.
The gain has a limit. An item with a lot of stock could generate hundreds of thousands of nearly idle rows, so there is a cap on rows per item and a replenishment process that keeps the pool stocked.
Two buyers of the same item arrive at checkout.
In a short transaction, checkout selects and locks available rows and removes them from the pool.
The second buyer skips over the rows already locked and locks others, without waiting.
The reservation is recorded as a row with a deadline, and locks exist only inside the short transactions that touch it.
A replenishment process keeps the pool stocked when it runs low.
A race can empty the pool before replenishment arrives; so the reservation itself refills the pool on the spot and tries again.
| Aspecto | Single counter | One row per unit |
|---|---|---|
| How stock is stored | One row per item with a quantity counter | Available rows that checkout locks and removes from the pool |
| Under contention | Thousands of checkouts of the item collapse into a single lock | Buyers lock different rows and commit in parallel |
| What you pay | Every checkout of the item updates the same row | A new replenishment process to operate, monitor, and trigger, whose typical failure is the empty pool in the middle of the sale |
04 · ATOMICITY
Counting in one place, selling in another
The same account shows why the counter may not be able to live outside the database that holds the stock. Previously, Redis recorded the temporarily reserved units and MySQL recorded the units the merchant actually had. As a concurrency mechanism, Redis worked, but the two writes happened in different databases and could not be committed together.
Both errors cost money: selling the last unit to two buyers forces canceling an order, and hiding a unit that is still in the warehouse makes the merchant lose a sale. If the system updates MySQL and crashes before clearing the reservation in Redis, the purchase is complete, but Redis still treats those units as reserved, and the system hides stock that is available. In the reverse order the error is the opposite: the reservation is cleared, the crash comes before the update, and the units go back on sale even though they are already sold. Swapping the order only changes which failure is possible.
O two-phase commit also doesn't work: it would require both databases to take part in the same coordination protocol, which Redis could not do.
05 · DEADLINE
Reservations nobody says have ended
Reserving is not buying. If payment fails or the buyer leaves checkout, there is an explicit signal that releases the reservation. If the buyer simply closes the laptop, no signal arrives, and, if nothing returns the units, the sale shows as sold out while the warehouse still has stock. That is why the deadline must live in the data, and something still running must act when it passes.
With a Redis counter, the tempting way out is a TTL, but a TTL on the counter key would delete the whole counter, not one buyer's reservation. A key per reservation doesn't help either: Redis has no fast way to get the count from a pile of per-reservation keys.
For the MySQL design, Hello Interview says the Shopify post does not say what it did and gives its own guess: store the reservation as a row with a deadline and count as active only the reservations that have not yet expired. Once the deadline passes, the reservation stops counting and the next replenishment returns the capacity. A cleanup routine is still desirable, but it is garbage collection, not correctness.
06 · ENTRY
The crowd before the database
Even a correct inventory design needs protection against millions of users arriving at once, which the material lists as a separate deep dive. A virtual waiting room routes the excess users to a custom queue, preserving the experience and protecting the origin servers from being overwhelmed with requests.
A well-built waiting room remembers each visitor's state, so that no one loses their place in the queue or has to re-enter if they leave the site, and it opens spots faster by tracking the flow in and out.
Besides the queue, the server itself needs to protect itself. Throughput is everything that arrives; goodput is the part handled without errors and with latency low enough for the client to make use of the response. Shedding load allows goodput to be maintained even when offered load grows, and rejecting early is the cheapest point to shed, at the cost of visibility.
A crowd tries to open the sale at the same time.
The waiting room routes the excess users to a custom queue, instead of letting them reach the origin.
The room keeps each visitor's state, so they hold their place in the queue.
Only admitted traffic reaches checkout, which can still shed early whatever exceeds its capacity.
The inventory database receives only the load left over after these layers.
The public material treats fairness of access to limited stock as a separate deep dive, alongside consistency, reservation expiry, and the crowd.
Frequently asked questions
What is Flash sale?
Classic interview design. Key points: reservations and concurrency, and overload control.
What does the Flash sale design cover?
It is organized in these sections: Few units, many people, The counter that goes negative, One row, one queue, Counting in one place, selling in another, Reservations nobody says have ended, and The crowd before the database.
How long is Flash sale and what level is it?
It takes about 16 minutes to read and is rated Senior level.
Now design it yourself
Run this case as an interview in the System Design school: you make the decisions, the tutor challenges them and you see how your design scores.