Food Delivery System
Design food delivery like DoorDash or Swiggy — customers browse restaurants, place orders, restaurants prepare, drivers deliver.
Introduction
Design food delivery like DoorDash or Swiggy — customers browse restaurants, place orders, restaurants prepare, drivers deliver. HLD spans search, order state machine, real-time driver location, dispatch matching, payments, and notifications.
Peak lunch/dinner traffic, geo-proximity queries, and three-sided marketplace (customer, restaurant, driver) make this a rich interview case study.
Understanding the topic
Key concepts
- Order states: PLACED → CONFIRMED → PREPARING → PICKED_UP → DELIVERED / CANCELLED.
- Dispatch: match available drivers near restaurant using geo index.
- Location stream: driver GPS every 5s → Kafka → Redis GEO for live map.
- Restaurant menu cache CDN + Redis; inventory decrement on order.
- ETA model from historical prep + distance + traffic.
- Payment hold on place, capture on delivery.
flowchart TBApp --> OrderSvcOrderSvc --> DispatchDispatch --> Geo[Redis GEO]OrderSvc --> PaymentOrderSvc --> Notify
Internal architecture
Architecture overview
flowchart TBApp --> OrderSvcOrderSvc --> DispatchDispatch --> Geo[Redis GEO]OrderSvc --> PaymentOrderSvc --> Notify
Step-by-step explanation
- Customer App → API Gateway → Order, Catalog, Payment, Dispatch services.
- POST /orders → saga: reserve menu items, authorize payment, notify restaurant.
- Restaurant accepts → Dispatch finds driver via GEORADIUS Redis 5km.
- Driver app streams location → Location Ingestion → Kafka → Redis GEO + customer map WS.
- Status updates push via Notification service FCM.
- Search restaurants by lat/lng in Elasticsearch with rating filters.
Informative example
Dispatch service finds nearest available drivers with Redis GEO:
@Servicepublic class DispatchService {private final StringRedisTemplate redis;private final KafkaTemplate<String, DispatchOffer> kafka;public DispatchService(StringRedisTemplate redis, KafkaTemplate<String, DispatchOffer> kafka) {this.redis = redis;this.kafka = kafka;}public void assignDriver(String orderId, double restaurantLat, double restaurantLng) {GeoResults<GeoLocation<String>> drivers = redis.opsForGeo().radius("drivers:online", new Circle(new Point(restaurantLng, restaurantLat),new Distance(5, Metrics.KILOMETERS)),GeoRadiusCommandArgs.newGeoRadiusArgs().limit(10).sortAscending());for (var result : drivers) {String driverId = result.getContent().getName();if (tryLockDriver(driverId)) {kafka.send("dispatch.offers", driverId, new DispatchOffer(orderId, driverId));return;}}scheduleRetry(orderId);}}
Geo key expires stale drivers. Saga compensates if no driver in 10min — refund and notify customer.
Real-world use
Real-world use cases
- Hyperlocal grocery quick commerce variant.
- Cloud kitchen multi-brand dispatch.
- Corporate catering scheduled orders batch dispatch.
- Emerging market cash-on-delivery payment path.
Best practices
- Idempotent order placement with client key.
- Separate read models for menu browsing vs order writes.
- Driver lock SET NX to prevent double assignment.
- Surge pricing from demand/supply stream optional module.
- Restaurant tablet offline mode queue orders.
- Monitor dispatch success rate and time-to-assign SLO.
Common mistakes
- Matching driver synchronously in POST /orders — timeout.
- No stale location cleanup — assign offline driver.
- Global menu DB without geo sharding for search latency.
- Capture payment on place not delivery — dispute handling wrong.
- Ignoring restaurant prep time in ETA — angry customers.
Advanced interview questions
Q1BeginnerCore entities in food delivery?
Q2BeginnerHow find nearby drivers?
Q3IntermediateOrder state machine importance?
Q4IntermediateHandle no driver available?
Q5AdvancedDesign Swiggy for 500k orders/day peak.
Summary
Food delivery HLD is a three-sided marketplace with geo dispatch. Order saga coordinates restaurant, payment, and driver assignment. Redis GEO powers real-time proximity matching. Location streaming via Kafka feeds live maps. Async dispatch avoids blocking order API. Video streaming shifts focus to CDN and transcoding scale.