How the waiting list gets notified
A restock with four units and thirty people waiting is where fairness is won or lost. This post is about the notifier: how it reads the queue in the exact order people joined, messages only as many as there are units to sell, phrases each notice in the store’s voice, and hands each recipient a short-lived reserve link — so the first to respond genuinely get the stock and nobody is oversold.
Key takeaways
- The notifier reads the per-SKU queue oldest-first, so people are told in the exact order they joined — no jumping.
- The batch is capped to the units available for this restock, so the system never invites more people than there is stock to sell.
- One Bedrock Haiku 4.5 call phrases the notice per restock; code personalises it and injects each recipient’s reserve link.
- Each recipient is marked notified for this restock id, so a retry or a re-fired batch can never text the same person twice.
- Opt-out is checked again at send time, and the reserve link — not the model — is what makes first-come, first-served real.
The moment fairness is won or lost
A restock with four units and thirty people waiting is where a back-in-stock system either keeps its promise or breaks it. Blast all thirty and you’ve started a scramble: four win, twenty-six are told the thing they wanted is gone again before they’ve finished reading, and if several buy the last unit in the same minute you’ve oversold. The notifier exists to make that moment orderly. By the time it runs, Part 3 has already handed it everything it needs on the queue: the SKU, the restock id, and the number of units available. Its whole task is to turn that into the right notices, to the right people, in the right order — and to stop.
It reads the waiting list for that SKU straight from the requests table, which is stored sorted by join time, so the query comes back oldest-first with no sorting to do. It walks that list from the front, and it counts. The unit count is a hard cap: for four chairs it will notify at most four people, then stop, no matter how many are waiting behind them. This is the single rule that makes overselling impossible at the notice stage — you cannot oversell a queue you never invited past the number of units you have.
Oldest first, capped, and skipping the suppressed
Walking the queue isn’t quite “take the first four”, because a couple of the people at the front may no longer be reachable. As it goes, the notifier checks each candidate against two things: the opt-out list (someone who unsubscribed after joining is skipped and never counts against the cap), and whether they’ve already been notified for this restock id (so a re-run doesn’t double-message anyone). A skipped person doesn’t consume one of the four slots — the notifier simply moves to the next eligible person — so four reachable people are always told for four units, not “four positions, some of them dead ends”. It fills the cap with people who can actually act on it.
For each person it does notify, it writes a marker recording that this request was notified for this restock id before the message goes out, using a conditional write. That ordering matters: the marker is what makes the whole batch idempotent. If the SQS message is redelivered, or the batch runs twice, the second pass sees the marker and skips — so exactly one notice reaches each person per restock, even though the underlying queue delivery is at-least-once. The reserve link the message carries is minted here too, one per recipient, tied to that person and that restock, and live for only a short window (Part 5 is entirely about what that link does).
One notice, phrased once
Wording is the one part a shop actually cares about, so this is where the single model call lives — and it’s one call per restock, not one per person. The notice for “the walnut dining chair is back” reads the same for everyone in the batch, so Bedrock’s Claude Haiku 4.5 is asked once to phrase it in the store’s voice, handed only the facts it may use: the product name, the store name, and a placeholder where the reserve link will go. It is told to write one short message that says the item is back, that the recipient is near the front of the list, and that the link holds one for a short window — and to use only those facts. Then code takes that single phrasing and personalises the cheap parts — the first name, the reserve link — per recipient. Phrasing once and templating the rest keeps the model cost to a fraction of a penny per restock rather than per message, and keeps every notice in a batch consistent.
The reserve link is never written by the model. The model emits a token like {{reserve}}, and the code substitutes each recipient’s real, signed reserve URL afterwards — because a language model is perfectly capable of subtly mistyping a URL, and a broken reserve link is the one error that quietly wastes the whole notice. The draft is validated before anything sends: under the SMS length limit, exactly one link, an opt-out hint, no invented promises about price or delivery. If the draft fails, or Bedrock is slow, the notifier falls back to a fixed template — “Good news — {product} is back at {store}. You’re near the front of the list; this link holds one for you for {window} minutes: {link}. Reply STOP to opt out.” — which is plainer but always correct and always on time. The model supplies the warmth; the code guarantees the link, the cap, and the order.
Design rules that shaped the notifier
- Oldest first, always. The queue is read in join order and walked from the front; nobody is reordered or jumped.
- The cap is the unit count. At most one notice per available unit — the loop stops when the cap is filled, so it can’t oversell.
- Skip, don’t spend a slot. An opt-out or already-notified person is skipped without using up one of the units.
- Mark before you send. A conditional “notified for this restock” marker makes the batch idempotent — one notice each, even on retry.
- Phrase once, personalise in code. One Haiku call per restock; the name and the reserve link are injected deterministically.
- The link is the code’s job. The model emits a token; the real signed reserve URL is substituted per recipient so it can never be mangled.