How a reservation gets held
A notice without a hold is just a starting gun for a scramble. This post is about the reservation: how clicking the reserve link locks a single unit for a short window — safely, without ever taking stock below zero — and how a scheduled sweep returns any hold that isn’t used to the next person waiting, so the queue keeps moving and stale requests fall away.
Key takeaways
- Each notice carries a short-lived, signed reserve link; clicking it holds a single unit for that person for a set window.
- The hold is a conditional write that decrements the available count and can never take it below zero — so it can’t oversell.
- The link is single-use and tied to one request and one restock, so it can’t be forwarded, replayed, or shared to jump the queue.
- An EventBridge Scheduler sweep expires holds that aren’t converted in time, returning the unit to the pool for the next person.
- The same sweep expires stale requests, so a queue full of people who’ve moved on doesn’t block the ones who still want the item.
A notice without a hold is a starting gun
The notice in Part 4 does its job only if being told actually means getting the thing. If the message just said “it’s back, go and buy it”, then four notices for four chairs would still be a race — the fastest tapper wins, being first in the queue counts for nothing, and if two people reach checkout with the last chair in the same few seconds the shop oversells. The reserve link is what turns the notice from a starting gun into a genuine reservation. It carries a signed token unique to one recipient and one restock, and clicking it does one thing: it holds a single unit for that person for a short window — long enough to get through checkout, short enough that the queue keeps moving.
The link lands on its own Lambda Function URL — the third public surface, separate from capture and the inventory webhook, because it’s a different job with a different shape: a customer clicking a link in a text and expecting to end up at checkout. The function validates the token’s signature (so a guessed or edited link is rejected), checks it hasn’t already been used or expired, and only then attempts the hold. Everything about this step is built around one guarantee: the shop can promise a held unit to whoever clicks, without ever promising the same unit twice.
The hold that cannot oversell
The hold itself is a single conditional write, and it’s the linchpin of the never-oversell promise. The restock record for that SKU carries a count of units still available to hold. When a reserve link is clicked, the function decrements that count with a condition that it stays at or above zero, and writes a reservation row keyed to the token with an expiry timestamp a few minutes out. If the count is already zero — every unit in this restock is spoken for — the condition fails, the hold is refused, and the shopper is shown an honest “just gone, we’ll keep your place” rather than a false promise. Because the decrement is atomic, two people clicking their links in the same instant can never both take the last unit: DynamoDB serialises the two writes, one succeeds, one sees zero and is refused. There is no window in which the shop believes it has stock it doesn’t.
A successful hold writes a reservation and hands the shopper to the store’s checkout with the item reserved — a real cart, held under their name. The reservation row records who holds it, for which restock, and when it expires. That expiry is the important half of the design: a hold is not a sale. Someone can click the link, glance at the price, and wander off, and if a held unit could sit reserved forever, the queue behind them would be stuck — a chair reserved for a person who’s never coming back is exactly as useless as a chair sold to a bot. So every hold has a clock on it, and something has to watch that clock.
The sweep that keeps the line moving
Watching a clock across thousands of holds is a job for something that runs on a schedule, not a trigger — the thing that needs acting on is an event that didn’t happen: a checkout that never completed. That’s the expiry sweep, driven by EventBridge Scheduler on a short cadence (every few minutes). Each run queries the reservations table for holds that are past their expiry and were never converted to a sale. For each one, it does the mirror image of the hold: it returns the unit by incrementing the available count back up on the restock record, and marks the reservation expired so it’s never processed twice. The increment is safe to run repeatedly because the expired marker makes it idempotent — a hold is returned exactly once, however many times the sweep runs.
Returning the unit is only half of it; the point is to give it to the next person in line, not to whoever happens to click a stale link. So when the sweep frees a unit and finds people still waiting on that SKU, it enqueues a small top-up notify batch — the same job Part 4 processes — for the number of units just freed. Marcus, fifth in the queue, is told only now, because a unit has genuinely become available for him and the restock’s cap has room again. The queue always advances by exactly the number of holds that lapsed, in order, and a latecomer who was never on the list is never slipped in ahead of the people who waited. The same sweep also does a quieter housekeeping pass: requests that have sat on a queue past their time-to-live — someone who asked months ago and clearly moved on — are expired off the list, so a restock isn’t spent messaging people who no longer care while the genuinely keen wait behind them.
Design rules that shaped the reservation
- A notice buys a hold, not a race. The reserve link holds a single unit for the recipient for a short, fixed window.
- The decrement can’t go below zero. A conditional write makes overselling impossible even when two links are clicked at once.
- One link, one use. The token is signed, single-use, and tied to one request and one restock — it can’t be shared or replayed.
- A hold is not a sale. Every hold has an expiry, because a unit reserved forever blocks the whole queue behind it.
- Freed units go to the next in line. The sweep returns a lapsed hold and tops up a notice to the next person, never a latecomer.
- Stale requests fall away. Time-to-live clears people who’ve moved on, so a restock isn’t wasted on a queue full of ghosts.