Inventory Reservation

What it is

Think about buying the last seat on a flight, or the last unit of a popular item in a shop. The moment you click "buy", the seat or the unit is held just for you while you enter your payment details. If you finish in time, it becomes yours for good. If you take too long, or you cancel, the hold ends and it goes back to being available for someone else. The one rule that must never break: two different buyers can never both end up owning the same unit. When many buyers try to reserve the last units at the exact same moment, this is sometimes called a race condition, because what actually happens depends on the order the computer processes each buyer's request in.

The core idea

A reservation moves through a small lifecycle:

Every reservation also carries a deadline. If it is still active when that deadline passes, its units return to free stock automatically, as if the buyer had released it themselves. Confirming or releasing a reservation again after it has already been confirmed, released, or timed out must do nothing. It must never hand back the same units a second time.

Example: reserve, confirm, release, and a deadline

Add 10 units of an item. Reserve 3 of them: 7 are now free. Confirm that reservation: it becomes a sale, and 7 are still free (confirming does not free anything up, it just makes the hold permanent).

Now start over. Add 10 units again and reserve 3 with a deadline of 5 time units from now. 7 are free. Instead of confirming, release the reservation: the 3 units come back, so 10 are free again. Releasing that same reservation a second time changes nothing, since it already finished.

One more case: add 5 units and reserve 3 with a deadline of 5. 2 are free. Time moves to 10, which is past the deadline, and the hold's 3 units come back on their own: 5 are free again. Trying to confirm that reservation now fails, since it is no longer active.

The many-buyers-at-once problem

Say only 1 unit is left, and 5 buyers all try to reserve it at the same instant. A natural way to write this, "check how many are free, then take the units", has a gap: if two buyers both check and see "1 is free" before either one has updated that number, both go on to take the unit, and now 2 units are sold out of 1. This is the same mistake as two people both checking a joint bank balance before either one withdraws, each seeing enough money, and both withdrawing at once.

The fix is to make the check and the take happen as a single step that nothing else can interrupt, usually by holding one lock (or an equivalent tool your language provides) across both parts. Whichever buyer reaches that step first gets the unit, and every other buyer sees the updated, lower number before they get their turn.

Where you meet this

When to choose it: stock is short and paying takes time, so a customer should not lose the item halfway through checkout.

When not to: stock is plenty, or paying is instant. Then "check and take at payment time" is simpler and needs no timers. A hold that lasts too long also hides stock from real buyers, so keep holds short and always let them expire.

Common bugs

Keep it fast

Keep a running free-stock count per item instead of recomputing it from every reservation you have ever made. Look up a reservation by its id directly, for example with a map or dictionary, instead of scanning a list of every reservation to find it.

Learn more

This same hold-then-confirm-or-release shape shows up anywhere stock, seats, or any other limited resource is shared across many buyers at once: ticket booking, warehouse systems, and database row locking all use some version of it.

Go to the Inventory Reservation challenge