This question evaluates system design competency, focusing on order lifecycle modeling and state-machine enforcement, idempotency and data consistency, event-driven integration, real-time status propagation, and scaling across stores.
## System Design: Coffee Ordering System
Design a system for a coffee shop (or chain) that supports ordering drinks.
### Core use cases
- Customer browses menu and places an order (pickup or in-store).
- Customer customizes items (size, milk type, add-ons) and sets quantity.
- System calculates total price (including tax/discounts).
- Payment can be processed (or order marked as pay-at-store).
- Baristas see a **queue** of incoming orders and update status: `PLACED → PAID (optional) → IN_PROGRESS → READY → COMPLETED/CANCELLED`.
- Customer can see order status updates.
### Constraints / scale (assume)
- Start with one store, then extend to many stores.
- Peak: thousands of orders/min across all stores.
- Status updates should feel near-real-time to customers.
### What to cover
- APIs (or events) for placing orders and status updates.
- Data model for menu, orders, payments.
- High-level architecture and major services.
- Consistency, idempotency, and failure handling (e.g., retries, duplicate submits).
- How you would scale to many stores.
Overview: This question evaluates system design competency, focusing on order lifecycle modeling and state-machine enforcement, idempotency and data consistency, event-driven integration, real-time status propagation, and scaling across stores.
Community answers
Answer by Xiaoming
Thanks
Answer by Andy Outlook
Clarify requirements (fast)
> Functional
Menu: categories, items, options/modifiers, pricing rules.
Order: create, update, cancel; compute totals.
Payment: online card/wallet (optional), or pay-in-store.
Store routing: order goes to a specific store (nearest or chosen).
Production queue: barista view with ordering/priority, status updates.
Customer tracking: see current status; notifications when ready.
Answer by vkk123
Can we also have high level component design for this
Design a system for a coffee shop (and later a chain of stores) that lets customers order drinks for pickup or in-store consumption, and lets baristas work the order queue.
This was a time-boxed (~30 minute) system design round, so prioritize the core ordering flow, the order state machine, and how it scales from one store to many — depth over breadth.
The system must support these core use cases:
A customer browses a store's menu and places an order for
pickup
or
in-store
.
The customer customizes each item (size, milk type, add-ons) and sets a quantity per item.
The system computes the total price (line totals, tax, any discounts)
server-side
.
Payment is either processed online or the order is marked
pay-at-store
.
Baristas see a live
queue
of incoming orders and advance each order's status through a state machine:
PLACED → PAID (optional) → IN_PROGRESS → READY → COMPLETED / CANCELLED
.
The customer sees near-real-time status updates and is notified when the drink is ready.
Walk through the APIs/events, the data model, the high-level architecture and major services, how you keep the system correct under retries and failures, and how you scale from one store to many.
Constraints & Assumptions
Start with
one store
, then extend to
many stores
(and eventually multiple regions).
Peak load:
thousands of orders/minute
across all stores — treat this as roughly
≈100
orders/sec at peak. Assume reads (menu browsing, status checks) dominate writes, on the order of a
50:1
ratio.
Status updates should feel
near-real-time
(low single-digit seconds) to customers.
Money must be correct:
no duplicate orders, no double charges
, even under client retries and at-least-once webhook delivery. Correctness for money and order submission takes priority over availability.
Pricing and tax are computed
per store
(sales tax varies by jurisdiction).
Menus change rarely and are highly cacheable; prices on a placed order must not change retroactively.
Out of scope unless you choose to mention hooks: inventory/supply chain, loyalty accrual, delivery/driver dispatch, POS hardware specifics.
Clarifying Questions to Ask Guidance
Is pricing and tax
store-specific
(sales tax varies by jurisdiction)? Does each store have its own menu and availability?
Do we need
order-ahead with a scheduled pickup time
, or only "make it now"?
For pay-at-store orders, when is the order allowed to start being made — before or only after payment is collected, and who records that money was taken?
Should an order be
cancellable
after the barista has started it, and who is allowed to cancel (customer vs. staff)?
Single region first, or multi-region from day one?
Roughly how many stores are we targeting, and what read:write ratio should we design around?
What a Strong Answer Covers Guidance
Requirements split
into functional vs. non-functional, with explicit, sensible scoping of what's in and out.
A clear,
server-enforced order state machine
with explicit allowed transitions and concurrency control (two baristas can't double-advance the same order).
Idempotent order creation
and
effectively-once payment capture
, with the PSP webhook (not the client) treated as the source of truth for online payments.
A data model that
snapshots prices/modifiers
onto the order so later menu edits don't change historical orders, with idempotency encoded as DB constraints.
Reliable event propagation (e.g.
outbox + event bus
) and a justified read/write split, with menus served from cache/CDN.
A
realtime delivery
strategy (WebSocket/SSE, reconnect/catch-up behavior, polling fallback) sized against concurrent in-flight orders.
A coherent
sharding/partitioning
story (by store) and honest identification of the real bottlenecks (payment path, realtime connection count) versus the modest raw write throughput.
Security, privacy, and observability
: RBAC, PCI scope minimization, the key SLOs and alerts.
Follow-up Questions Guidance
After the design, the interviewer for this round asked two SQL questions against the resulting schema, then two scenario follow-ups on the design:
SQL against the schema:
Write a query to find the
user who spent the most last month
. What does "spend" mean precisely given your data model?
Write a query to find
users who have never spent anything
. How do you avoid the classic
NULL
and
LEFT JOIN
-becomes-inner-join traps?
Scenario follow-ups on the design:
A payment is captured by the PSP but the webhook that would advance the order to
PAID
is lost. How does the order eventually reconcile?
How would you handle a store losing connectivity to the cloud during the morning rush without losing or duplicating orders, and how does your design change to support
scheduled order-ahead
(e.g. "have it ready at 8:15am")?