100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

How Would You Design a Food Delivery System?

Learn how to design a food delivery platform: order state machine, geospatial driver tracking, and real-time dispatch matching.

hardQ45 of 224 in System Design Est. time: 6 minsLast updated:
Open Code Lab

Expected Interview Answer

A food delivery system is a three-sided marketplace connecting customers, restaurants, and delivery drivers, built around order management, real-time location tracking, and a matching engine that assigns the nearest available driver to each order.

The core write path takes an order through states (placed, accepted by restaurant, preparing, picked up, delivered) persisted in a relational store for strong consistency on payment and order status, while driver locations stream continuously through a lightweight, high-write path such as a geospatial index (geohash or quadtree) backed by an in-memory store like Redis for fast proximity queries. A dispatch service periodically or event-drivenly finds the nearest idle drivers to a new order, factoring in ETA, driver rating, and load balancing across the fleet. Real-time updates to customers and drivers flow over WebSockets or push notifications rather than polling, and the system separates read-heavy restaurant catalog browsing (cacheable, eventually consistent) from write-heavy order and location updates (strongly consistent, low latency).

  • Geospatial indexing enables fast nearest-driver queries at city scale
  • Separating catalog reads from order writes lets each be scaled and cached independently
  • Event-driven order state transitions keep customers, restaurants, and drivers in sync in real time
  • Decoupled dispatch logic allows tuning matching quality without touching the order pipeline

AI Mentor Explanation

Designing food delivery is like organizing a stadium where the scoreboard operator (order service) tracks every match state precisely โ€” toss, innings, result โ€” while a separate team of scouts continuously reports player positions on the field using flags (geospatial index) for instant lookup. When a ball needs fielding, the captain (dispatch engine) checks the scoutsโ€™ live flag positions to pick the nearest fielder rather than re-surveying the whole ground. The scoreboard stays authoritative and consistent while the flag system stays fast and constantly refreshed. That split between a slow, correct ledger and a fast, disposable location index is exactly how food delivery systems separate order state from driver tracking.

Step-by-Step Explanation

  1. Step 1

    Model the order lifecycle

    Define states (placed, accepted, preparing, picked up, delivered) in a strongly consistent relational store with a state machine to prevent invalid transitions.

  2. Step 2

    Stream driver locations separately

    Drivers push GPS pings on a fast, lossy-tolerant path into a geospatial index (geohash/quadtree in Redis) optimized for proximity queries, not the order database.

  3. Step 3

    Run the dispatch/matching engine

    On a new order, query nearby idle drivers via the geospatial index, score them by ETA/rating/load, and assign the best match.

  4. Step 4

    Push real-time updates

    Notify customer, restaurant, and driver of every state change over WebSockets/push notifications instead of client polling.

What Interviewer Expects

  • Separates the durable order/payment path from the fast driver-location path
  • Names a concrete geospatial technique (geohash, quadtree, or Redis GEO commands)
  • Describes the dispatch/matching engine and what it optimizes for (ETA, fairness, rating)
  • Mentions real-time delivery via WebSockets/push rather than polling

Common Mistakes

  • Storing driver GPS pings in the same relational table as orders, causing write contention
  • Ignoring how the system finds the nearest driver at scale (no geospatial index mentioned)
  • Forgetting real-time notification mechanisms and assuming clients poll for updates
  • Not discussing what happens when no driver is available or an order is cancelled mid-flight

Best Answer (HR Friendly)

โ€œI would split the system into two halves: a reliable order and payment pipeline that tracks exactly what state every order is in, and a fast, constantly updating map of where every driver currently is. A matching service uses that live map to instantly find the closest available driver for a new order, and everyone involved gets real-time updates as the order moves through pickup and delivery.โ€

Code Example

Dispatch: find nearest idle driver using a geospatial index
async function assignDriver(order) {
  const { lat, lng } = order.restaurantLocation

  // Redis GEO-style radius query against idle drivers only
  const candidates = await geoIndex.radiusQuery({
    lat,
    lng,
    radiusKm: 5,
    status: "idle",
    limit: 20,
  })

  if (candidates.length === 0) {
    return expandSearchRadius(order)
  }

  const scored = candidates.map((driver) => ({
    driver,
    score: scoreCandidate(driver, order), // ETA, rating, current load
  }))

  const best = scored.sort((a, b) => b.score - a.score)[0].driver

  await orderService.transition(order.id, "assigned", { driverId: best.id })
  await notifyRealtime(best.id, order)
  return best
}

Follow-up Questions

  • How would you handle a driver going offline mid-delivery?
  • How would you scale the geospatial index across multiple cities or regions?
  • How do you avoid double-assigning the same driver to two orders simultaneously?
  • How would you design surge pricing on top of this architecture?

MCQ Practice

1. Why do food delivery systems typically store driver GPS pings separately from order records?

Driver locations update far more frequently and tolerate loss, while order state must be durable and consistent, so they use different storage optimized for each.

2. What data structure is commonly used to find the nearest available drivers efficiently?

Geospatial indexes like geohash or quadtrees allow efficient proximity queries instead of scanning every driver.

3. Why do food delivery apps use WebSockets or push notifications instead of client polling for order status?

Push-based delivery avoids constant polling overhead and gives customers and drivers near-instant updates as order state changes.

Flash Cards

Why separate order state from driver location storage? โ€” Orders need strong consistency and durability; driver locations are high-frequency and loss-tolerant, so each gets different storage.

What powers nearest-driver lookups? โ€” A geospatial index such as geohash or a quadtree, often backed by an in-memory store like Redis.

What does the dispatch engine optimize for? โ€” ETA, driver rating, and fleet load balancing when assigning a driver to an order.

How are customers/drivers notified of order changes? โ€” Real time, via WebSockets or push notifications, not polling.

1 / 4

Continue Learning