System Design Deep Dive - 14 Design Food Delivery

Post by ailswan May. 07, 2026

ไธญๆ–‡ โ†“

๐ŸŽฏ Design Food Delivery

1๏ธโƒฃ Core Framework

When discussing Food Delivery design, I frame it as:

  1. Core flows: browse restaurant, place order, deliver order
  2. Restaurant, menu, cart, and order management
  3. Payment and checkout
  4. Order state machine
  5. Dasher / courier dispatch
  6. Real-time tracking and ETA
  7. Inventory, menu availability, and cancellation
  8. Trade-offs: consistency vs latency vs marketplace efficiency

2๏ธโƒฃ Core Requirements


Functional Requirements


Non-functional Requirements


๐Ÿ‘‰ Interview Answer

A food delivery system is a marketplace connecting customers, restaurants, and couriers.

The core flows are restaurant discovery, order placement, restaurant preparation, courier dispatch, delivery tracking, and payment.

The main challenge is coordinating many real-time states while keeping order and payment correctness strong.


3๏ธโƒฃ Main APIs


Search Restaurants

GET /api/restaurants?lat=40.7128&lng=-74.0060&query=sushi

Get Menu

GET /api/restaurants/{restaurantId}/menu

Create Cart

POST /api/cart

Request:

{
  "userId": "u123",
  "restaurantId": "r456",
  "items": [
    {
      "menuItemId": "m1",
      "quantity": 2,
      "options": {
        "spiceLevel": "medium"
      }
    }
  ]
}

Place Order

POST /api/orders

Request:

{
  "userId": "u123",
  "cartId": "c789",
  "deliveryAddressId": "addr1",
  "paymentMethodId": "pm1",
  "tipAmount": 5.00,
  "promoCode": "SAVE10"
}

Update Order State

POST /api/orders/{orderId}/state

Track Delivery

GET /api/orders/{orderId}/tracking

๐Ÿ‘‰ Interview Answer

I would separate APIs for restaurant search, menu retrieval, cart management, order creation, order state updates, and delivery tracking.

Search and menu reads are read-heavy, while order creation and payment require stronger correctness.


4๏ธโƒฃ Data Model


Restaurant Table

restaurant (
  restaurant_id VARCHAR PRIMARY KEY,
  name VARCHAR,
  location_lat DOUBLE,
  location_lng DOUBLE,
  status VARCHAR,
  rating DOUBLE,
  delivery_radius_km DOUBLE,
  created_at TIMESTAMP
)

menu_item (
  item_id VARCHAR PRIMARY KEY,
  restaurant_id VARCHAR,
  name VARCHAR,
  description TEXT,
  price DECIMAL,
  available BOOLEAN,
  category VARCHAR,
  options JSON,
  updated_at TIMESTAMP
)

Cart Table

cart (
  cart_id VARCHAR PRIMARY KEY,
  user_id VARCHAR,
  restaurant_id VARCHAR,
  status VARCHAR,
  created_at TIMESTAMP,
  updated_at TIMESTAMP
)

Cart Item Table

cart_item (
  cart_id VARCHAR,
  menu_item_id VARCHAR,
  quantity INT,
  selected_options JSON,
  price_snapshot DECIMAL,
  PRIMARY KEY (cart_id, menu_item_id)
)

Order Table

order (
  order_id VARCHAR PRIMARY KEY,
  user_id VARCHAR,
  restaurant_id VARCHAR,
  courier_id VARCHAR,
  state VARCHAR,
  subtotal DECIMAL,
  delivery_fee DECIMAL,
  tax DECIMAL,
  tip DECIMAL,
  discount DECIMAL,
  total DECIMAL,
  payment_status VARCHAR,
  created_at TIMESTAMP,
  updated_at TIMESTAMP
)

Order Event Table

order_event (
  event_id VARCHAR PRIMARY KEY,
  order_id VARCHAR,
  actor_id VARCHAR,
  event_type VARCHAR,
  created_at TIMESTAMP,
  metadata JSON
)

๐Ÿ‘‰ Interview Answer

I would separate restaurants, menus, carts, orders, and order events.

Menu data is read-heavy and can be cached.

Orders are durable transactional records, while order events provide an audit trail for debugging, customer support, and reconciliation.


5๏ธโƒฃ Restaurant Search and Menu Serving


Restaurant Search Inputs


Search Flow

User opens app
โ†’ Location service gets user location
โ†’ Restaurant service finds nearby restaurants
โ†’ Filter open/available restaurants
โ†’ Rank by ETA, rating, relevance, fees
โ†’ Return list

Menus should be cached because they are read-heavy.

Cache:


๐Ÿ‘‰ Interview Answer

Restaurant discovery is a geo-search problem.

I would find restaurants within the delivery radius, filter by open status and availability, then rank by ETA, rating, relevance, fees, and promotions.

Menu data is read-heavy, so it should be cached aggressively, while availability may need shorter TTLs.


6๏ธโƒฃ Cart and Checkout


Cart Responsibilities


Price Snapshot

When user adds item to cart, store price snapshot.

Why?


Checkout Validation

Before order creation:


๐Ÿ‘‰ Interview Answer

Cart is temporary, but checkout must revalidate everything.

Before creating an order, I would check restaurant availability, menu item availability, delivery address, promotion validity, final price, and payment pre-authorization.

This prevents stale cart data from creating invalid orders.


7๏ธโƒฃ Order State Machine


Common States

CREATED
PAYMENT_AUTHORIZED
SENT_TO_RESTAURANT
RESTAURANT_ACCEPTED
PREPARING
READY_FOR_PICKUP
COURIER_ASSIGNED
PICKED_UP
OUT_FOR_DELIVERY
DELIVERED
CANCELLED
REFUNDED

Why State Machine Matters


Example Transitions

CREATED โ†’ PAYMENT_AUTHORIZED
PAYMENT_AUTHORIZED โ†’ SENT_TO_RESTAURANT
SENT_TO_RESTAURANT โ†’ RESTAURANT_ACCEPTED
RESTAURANT_ACCEPTED โ†’ PREPARING
PREPARING โ†’ READY_FOR_PICKUP
READY_FOR_PICKUP โ†’ PICKED_UP
PICKED_UP โ†’ OUT_FOR_DELIVERY
OUT_FOR_DELIVERY โ†’ DELIVERED

๐Ÿ‘‰ Interview Answer

I would model the order lifecycle as a state machine.

This prevents invalid transitions, makes retries safer, and coordinates restaurant preparation, courier delivery, notifications, and payment capture.

Payment capture should happen only after the order is accepted or after delivery, depending on business rules.


8๏ธโƒฃ Payment Flow


Payment Strategy

Use:

Pre-authorize at checkout
Capture after restaurant accepts or delivery completes
Refund on cancellation or failure

Why Pre-authorize?


Payment Flow

User places order
โ†’ Payment service pre-authorizes amount
โ†’ Order sent to restaurant
โ†’ Restaurant accepts
โ†’ Payment captured or held
โ†’ Order delivered
โ†’ Final adjustments/refunds if needed

Correctness

Use:


๐Ÿ‘‰ Interview Answer

Payment requires strong correctness.

I would pre-authorize payment during checkout, then capture after restaurant acceptance or after delivery depending on policy.

All payment operations should be idempotent to prevent duplicate charges or refunds.


9๏ธโƒฃ Restaurant Order Handling


Restaurant Flow

Order created
โ†’ Send to restaurant tablet/POS
โ†’ Restaurant accepts or rejects
โ†’ Restaurant estimates preparation time
โ†’ Kitchen prepares food
โ†’ Marks ready for pickup

Integration Options


Failure Cases


๐Ÿ‘‰ Interview Answer

After checkout, the order must be confirmed by the restaurant.

The restaurant can accept, reject, or update preparation time.

If the restaurant does not respond, the system should timeout, cancel the order, notify the user, and release or refund payment authorization.


๐Ÿ”Ÿ Courier Dispatch


Dispatch Inputs


Dispatch Flow

Restaurant accepts order
โ†’ Estimate preparation time
โ†’ Find nearby couriers
โ†’ Rank couriers
โ†’ Send offer to best courier
โ†’ Courier accepts
โ†’ Assign courier to order

Matching Strategy

Choose courier based on:


Avoid Double Assignment

Use atomic conditional update:

UPDATE courier
SET status = 'ASSIGNED'
WHERE courier_id = 'd123'
AND status = 'AVAILABLE';

๐Ÿ‘‰ Interview Answer

Courier dispatch is similar to ride matching, but it must also consider restaurant prep time.

The best courier is not always the closest courier. We want the courier to arrive near the time food is ready, minimizing both courier wait time and food delay.

Assignment must be atomic to avoid double assignment.


1๏ธโƒฃ1๏ธโƒฃ ETA System


ETA Types


Inputs


ETA Flow

Estimate prep time
โ†’ Estimate courier arrival time
โ†’ Estimate delivery travel time
โ†’ Combine into total ETA
โ†’ Update ETA as state changes

๐Ÿ‘‰ Interview Answer

Food delivery ETA is more complex than ride-sharing ETA because it includes both food preparation time and delivery time.

I would estimate restaurant prep time, courier travel time to pickup, and courier travel time to customer, then continuously update ETA as the order progresses.


1๏ธโƒฃ2๏ธโƒฃ Real-time Tracking


Tracking Flow

Courier sends location updates
โ†’ Location service stores latest location
โ†’ Tracking service streams updates to customer
โ†’ Customer app updates map

Tracking Requirements


Protocol

Use:


๐Ÿ‘‰ Interview Answer

For real-time delivery tracking, the courier app sends location updates every few seconds.

The tracking service streams relevant updates to the customer.

Slight delays are acceptable, so location tracking can be eventually consistent.


1๏ธโƒฃ3๏ธโƒฃ Inventory and Menu Availability


Availability Challenges


Strategies


๐Ÿ‘‰ Interview Answer

Menu and inventory data can become stale.

I would cache menu data for read performance, but always revalidate item availability and price at checkout.

The final order should store a price snapshot so historical orders remain consistent even if menu prices change later.


1๏ธโƒฃ4๏ธโƒฃ Promotions and Fees


Promotion Types


Fee Components


Validation

Promo validation checks:


๐Ÿ‘‰ Interview Answer

Promotions and fees should be calculated by a dedicated pricing service.

At checkout, the system validates promo eligibility, calculates tax, service fee, delivery fee, discount, tip, and final total.

The calculated price should be stored on the order for auditability.


1๏ธโƒฃ5๏ธโƒฃ Notifications


Notification Types


Channels


๐Ÿ‘‰ Interview Answer

Notifications are important because food delivery has many state changes.

I would publish order state change events, and a notification service would send push, SMS fallback, in-app updates, or email receipts asynchronously.


1๏ธโƒฃ6๏ธโƒฃ Scaling Patterns


Pattern 1: Separate Read-heavy and Transactional Paths


Pattern 2: Geo-sharded Marketplace

Shard by:

city / region / delivery zone

Why?


Pattern 3: Event-driven Order Pipeline

order state change
โ†’ event bus
โ†’ notification / dispatch / analytics / payment

Pattern 4: Cache Restaurant and Menu Data

Cache:


Pattern 5: Async Analytics

Track:


๐Ÿ‘‰ Interview Answer

To scale food delivery, I would separate read-heavy restaurant browsing from transactional order processing.

Marketplace operations like dispatch should be regionally sharded, because food delivery is naturally local.

Order state changes should publish events to drive notifications, dispatch, payment, and analytics.


1๏ธโƒฃ7๏ธโƒฃ Failure Handling


Common Failures


Strategies


๐Ÿ‘‰ Interview Answer

The system must be resilient to many partial failures.

Order creation and payment must be idempotent. Restaurant confirmation should have a timeout. Courier dispatch should retry with the next best courier.

All order state transitions should go through a state machine to avoid invalid or duplicated updates.


1๏ธโƒฃ8๏ธโƒฃ Consistency Model


Stronger Consistency Needed For


Eventual Consistency Acceptable For


๐Ÿ‘‰ Interview Answer

Food delivery systems require different consistency levels.

Order state, payment, cancellation, refund, and courier assignment require stronger correctness.

But courier location, ETA updates, restaurant ranking, notifications, and analytics can be eventually consistent.


1๏ธโƒฃ9๏ธโƒฃ Observability


Key Metrics


๐Ÿ‘‰ Interview Answer

I would monitor both system health and marketplace health.

Key metrics include checkout failure rate, restaurant acceptance rate, courier assignment latency, courier acceptance rate, ETA accuracy, cancellation rate, and payment failure rate.

These metrics show whether the marketplace is healthy and whether customers are getting reliable delivery.


2๏ธโƒฃ0๏ธโƒฃ End-to-End Flow


Browse Flow

User opens app
โ†’ Get user location
โ†’ Find nearby restaurants
โ†’ Filter open restaurants
โ†’ Rank by ETA, rating, relevance, promotions
โ†’ Return restaurant list

Order Flow

User builds cart
โ†’ Checkout validates cart
โ†’ Price calculated
โ†’ Payment pre-authorized
โ†’ Order created
โ†’ Restaurant confirms
โ†’ Courier dispatch starts

Delivery Flow

Restaurant prepares food
โ†’ Courier assigned
โ†’ Courier goes to restaurant
โ†’ Courier picks up food
โ†’ Courier delivers to customer
โ†’ Order marked delivered
โ†’ Payment captured
โ†’ Receipt sent

Key Insight

Food Delivery is not just ordering food โ€” it is a local three-sided marketplace coordinating customers, restaurants, and couriers.


๐Ÿง  Staff-Level Answer (Final)


๐Ÿ‘‰ Interview Answer (Full Version)

When designing a food delivery system, I think of it as a local three-sided marketplace connecting customers, restaurants, and couriers.

The system has three major flows: restaurant discovery, order placement, and delivery fulfillment.

Restaurant and menu browsing are read-heavy, so I would cache restaurant metadata, menus, popular items, and availability with short TTLs.

Checkout must be more strongly validated. Before creating an order, the system should revalidate restaurant status, item availability, delivery address, promotion eligibility, final price, and payment pre-authorization.

I would model each order as a state machine, with states such as created, payment authorized, sent to restaurant, restaurant accepted, preparing, ready for pickup, courier assigned, picked up, out for delivery, delivered, cancelled, and refunded.

Courier dispatch is geo-based, but unlike ride-sharing, it must also consider restaurant preparation time. The best courier is not always the closest one; we want the courier to arrive near the time food is ready.

Payment requires strong correctness, so I would use pre-authorization, capture, refunds, idempotency keys, and reconciliation jobs.

Real-time tracking and ETA updates can be eventually consistent, because small delays are acceptable.

I would use an event-driven architecture, where order state changes publish events to trigger notifications, dispatch, payment, analytics, and customer updates.

The main trade-offs are order correctness, payment correctness, ETA accuracy, marketplace efficiency, latency, and operational cost.

Ultimately, the goal is to reliably coordinate restaurants, couriers, and customers, while providing fast checkout, accurate ETA, and smooth delivery tracking.


โญ Final Insight

Food Delivery ็š„ๆ ธๅฟƒไธๆ˜ฏโ€œไธ‹ๅ•ไนฐ้ฃŸ็‰ฉโ€๏ผŒ ่€Œๆ˜ฏไธ€ไธชๅ่ฐƒ customerใ€restaurant ๅ’Œ courier ็š„ๆœฌๅœฐไธ‰่พน marketplace systemใ€‚

Implement