Business Systems13 min read

Design a Food Delivery System

Connect hungry customers with restaurants and delivery drivers β€” at scale
scope:Real-World Systemdifficulty:Advanced

Understanding the Problem

Food delivery platforms like DoorDash, UberEats, and Grubhub connect three parties: customers who want food, restaurants that prepare it, and drivers who deliver it. This three-sided marketplace is what makes this system uniquely challenging.

Functional Requirements:

  • Customers can browse nearby restaurants, view menus, and place orders.
  • Restaurants receive orders, confirm them, and update preparation status.
  • The system dispatches the best available driver to pick up and deliver the order.
  • Real-time tracking of delivery progress (driver location on map).
  • Customers and drivers can rate each other after delivery.

Non-Functional Requirements:

  • Low latency: Order placement must complete in <2 seconds.
  • Real-time tracking: Driver GPS updates every 3-5 seconds, visible to customers in near real-time.
  • Peak handling: Must handle lunch and dinner rush spikes without degradation.
  • ETA accuracy: Estimated delivery time should be within 5 minutes of actual delivery.
β–Έ The idea: order β†’ restaurant β†’ driver β†’ deliver

Estimation

Let's size this system for a large-scale platform:

  • 10M orders per day β€” that's ~115 orders/second average.
  • 1M restaurants on the platform, ~200K active at any time.
  • 500K active drivers β€” location updates every 4 seconds = 125K GPS writes/second.
  • Peak load: Lunch (11am-1pm) and dinner (6-8pm) see 3-5x average traffic β†’ ~5,000 orders/minute at peak.
  • 1M concurrent tracking sessions β€” customers watching their delivery on the map.
  • Storage: Each order ~2KB (items, addresses, status history). 10M/day Γ— 365 Γ— 2KB β‰ˆ 7 TB/year.

The key bottleneck is the real-time component: matching drivers, tracking locations, and predicting ETAs β€” all under tight latency budgets during peak hours.

Order Flow

The lifecycle of a food delivery order goes through several stages:

  1. Customer places order: Selects restaurant, adds items to cart, confirms payment. The order is created in the system.
  2. Restaurant confirms: Restaurant receives the order notification, confirms acceptance, and provides an estimated prep time (e.g., 20 minutes).
  3. Dispatch matches driver: The dispatch service finds the best available driver based on proximity, current load, and restaurant prep time. It may pre-dispatch before food is ready.
  4. Driver picks up: Driver arrives at restaurant, confirms pickup. Status updates flow to the customer in real-time.
  5. Delivery + tracking: Driver navigates to customer. GPS updates flow every few seconds. Customer sees the driver on a live map with a dynamic ETA.

Each transition triggers notifications to all relevant parties β€” the customer, restaurant, and driver all stay informed throughout.

β–Έ Order lifecycle: from placement to delivery
Click chart to zoom
Full order lifecycle: from placement through restaurant prep, driver dispatch, and real-time delivery tracking

Dispatch Algorithm

Driver matching is the heart of the system β€” it's an optimization problem balancing multiple factors:

  • Driver proximity: How far is the driver from the restaurant? Uses geospatial indexing (like a geohash or quadtree) to find nearby drivers efficiently.
  • Restaurant prep time: No point sending a driver immediately if food takes 25 minutes. Time the dispatch so the driver arrives just as food is ready.
  • Route distance: Factor in road network distance, not just straight-line. A driver 1 mile away across a highway might take longer than one 2 miles away on surface streets.
  • Driver current load: Is the driver already carrying another order? Batching is possible but adds complexity.

The dispatch engine scores available drivers and assigns the best match. This is similar to ride-sharing dispatch but with the added variable of restaurant prep time. The system may pre-dispatch β€” assign a driver early so they're en route to the restaurant just as food is ready.

β–Έ Dispatch and driver matching

ETA Prediction and Real-Time Tracking

ETA prediction uses an ML model trained on historical data:

  • Prep time prediction: Based on restaurant's historical prep times, current order volume, time of day, and order complexity.
  • Drive time prediction: Road network routing + live traffic data + time of day patterns.
  • Total ETA: prep_time + driver_to_restaurant + restaurant_to_customer + buffer.

Real-time tracking works through continuous GPS updates:

  • Driver app sends GPS coordinates every 3-5 seconds.
  • Updates flow to a Driver Location Cache (Redis with geospatial support) β€” not the main database.
  • Customer's tracking screen polls or receives WebSocket pushes with the latest position.
  • ETA is dynamically recalculated as the driver progresses.

Order batching: When a driver can efficiently pick up multiple orders from nearby restaurants, the system batches them. This increases driver utilization but requires careful ETA management β€” the second customer's delivery is slightly delayed.

β–Έ Full architecture
Note: Interview tip: The three-sided marketplace (customer, restaurant, driver) is what makes food delivery harder than ride-sharing. In ride-sharing, you match riders to drivers. Here, you also coordinate with restaurants whose prep times vary. The dispatch algorithm must account for this third party β€” dispatching too early wastes driver time, too late delays the customer.

Key Metrics

Order placement latency
Cart validation + payment hold + order creation
<2 seconds β€”
Dispatch matching time
Geospatial query + scoring + assignment
~3-10 seconds β€”
ETA accuracy
ML model with prep time + drive time + traffic
Β±5 minutes β€”
Peak throughput
Lunch/dinner rush with auto-scaling
~5K orders/min β€”
GPS update ingestion
500K drivers Γ— update every 4s
125K writes/sec β€”
Tracking sessions
WebSocket connections for live map
1M concurrent β€”

Quick check

Why is food delivery dispatch more complex than ride-sharing dispatch?

Continue reading