Marketplaces & booking
Food delivery - three parties and a promise
state machine, offers, ETA
What this board gets wrong on purpose
The tension
The ETA is shown before the restaurant has accepted and before any courier exists, so it is a promise made on behalf of two parties who have not agreed to it - built on a prep-time estimate the restaurant has every incentive to understate and no obligation to meet. Once it is displayed it is a commitment the business is refunded against, so it is stored and never recomputed, which means the customer is shown a number the system already knows is wrong for the fifteen minutes before anybody tells them. The courier side has the matching hole: dispatch optimises each offer greedily, one order at a time, so on a Friday at 19:30 the couriers nearest the busiest restaurants are consumed by whichever orders happened to be placed first, and the orders placed ninety seconds later - to the same restaurant - have no supply left within eight minutes. Nothing on this board is doing global assignment, and the reassignment loop sweetens the fee rather than fixing the allocation.
1 · Requirements
Three parties, none of whom work for us, and an order that moves between them. Every requirement below is shaped by the fact that two of the three can say no.
Ask these before designing
- Who owns the courier relationship? Employed riders can be assigned. Self-employed riders can only be offered, and the difference rewrites dispatch entirely.
- Is the ETA a promise or an estimate? If refunds are issued against it, it is a promise, and it must be stored rather than recomputed.
- Can an order be cancelled after the restaurant has started cooking? This is a commercial question - somebody pays for the food - and it decides where CANCELLED sits in the state machine.
- Batching: can one courier carry two orders? It roughly halves delivery cost and roughly doubles the complexity of both assignment and the ETA.
- How fresh must courier location be? 4 seconds is a smooth map and 50,000 writes/s. 15 seconds is a jerky map and 13,000 writes/s. This single number is the largest line in the infrastructure bill.
- What happens when no courier accepts? Sweeten and re-offer, widen the radius, or cancel and refund. All three are real answers and they are product decisions.
Functional
- Place an order, authorise payment, route it to a restaurant.
- Restaurant accepts or rejects, and reports a prep time.
- Offer the delivery to couriers and let them accept or decline; re-offer on timeout.
- Track the order through a legal sequence of states, driven by three different actors.
- Show live courier position and an ETA to the customer.
- Capture payment at handoff, refund on failure.
Non-functional
- A transition must be legal from the state the order is actually in. Two parties will act on the same order in the same second; exactly one may win.
- Order placement p99 under 1.2 s.
- Offer round trip under 30 s - a courier staring at a phone for longer declines.
- Ordering 99.95%, tracking 99.99% and degrading to text rather than a map.
- Demand is two spikes a day, not a curve: 40% of the day’s orders land between 19:00 and 20:30.
- Location writes are lossy by design. A dropped ping is a slightly jerkier map, never a wrong order.
Explicitly out of scope
Menu management, pricing and promotions, courier payouts and tax, restaurant onboarding, fraud, customer support tooling.
The rest of this board
Available on Tier Slate
This page publishes the question. The answer — 5 more written pages, an 8-step narrated walkthrough and a 5-table schema — is the board itself, and it opens in Tierslate.
- 5written pages
- 8walkthrough steps
- 5tables38 columns
5 pages behind this one
- Capacity estimation
- Storage estimation
- Availability
- How it works
- Deployment plan
More boards
Two-sided systems where inventory must not be sold twice.