System design · LLD design

Food Delivery System

Functional Requirements

  1. Customers can browse restaurants and their menu items (name, price, availability).
  2. Customers place an order with one or more items from a single restaurant.
  3. On placement, the restaurant must accept or reject the order within a time window; no response within that window auto-cancels it.
  4. On acceptance, the system finds and assigns an available nearby delivery partner to the order.
  5. Order moves through a defined lifecycle: PLACED → ACCEPTED → PREPARING → OUT_FOR_DELIVERY → DELIVERED, with CANCELLED reachable only before OUT_FOR_DELIVERY.
  6. Customers or restaurants can cancel an order only before it’s picked up by the delivery partner.
  7. Delivery partner has a status (AVAILABLE, BUSY, OFFLINE) that updates as they’re assigned to or complete an order.
  8. Customers can view real-time order status.
  9. Relevant parties (customer/restaurant/delivery partner) are notified on each status transition (trigger only — no need to design delivery mechanism).

Non-Functional Requirements

  1. Extensibility — delivery-partner assignment strategy (nearest, best-rated, etc.) should be swappable without touching core logic.
  2. Scalability — support growth in restaurants, delivery partners, and concurrent orders without restructuring.
  3. Concurrency — safely handle concurrent partner assignment so no two orders claim the same partner, and no partner is double-booked; also handle concurrent status updates on the same order.
  4. Consistency — order status transitions must be atomic and reject invalid transitions (e.g., cancelling an already-delivered order).
  5. Low latency — delivery-partner matching sits on the user-facing critical path and must resolve quickly.

Entities and class

OrderStatus : enum

PLACED , ACCEPTED , PREPARING , OUT_FOR_DELIVERY , DELIVERED, CANCELLED

Menu
-menuID
-HashMap<String, MenuItem> menuItem
+addItem(MenuItem)

MenuItem
-id
-name
-price
-available : Atomicboolean

Restaurant
-restaurantId
-Menu menu
-address: string

+addToMenu(MenuItem)
menu.addItem(menuitem)

Customer
-id
-name
-address

OrderItem
-id
-MenuItem
-quantity

Order
-orderId
-resurant
-customer
-List<OrderItems> orderitems
-price
-orderStatus
-expiryTime

canCancel() : boolean

if(status not in “OUT_FOR_DELIVER” or “DELIVERED” )
Update status to cancelled and return true else false