# Design a Mobile Food Delivery App: DoorDash and Uber Eats

Source: https://www.techinterview.org/post/3233475300/mobile-system-design-food-delivery-doordash-uber-eats/
Updated: 2026-06-30 · techinterview.org

"Design a food-delivery app" is the consumer-side mobile-system-design counterpart to the courier-side question. The interviewer wants to see how you handle restaurant search at scale, cart state across devices, real-time order tracking, and the unforgiving UX of "where is my food right now."

## Clarify scope

- Eater app only, or also restaurant tablet and courier app?

- Single market or global? (Localization, currencies, address formats)

- Group ordering for office lunches?

- Subscription tier (DashPass / Uber One)?

## Core flows

- Discover: search/browse restaurants by location and cuisine

- Configure: pick items, modifiers, special instructions; cart updates

- Pay: address, tip, payment method, place order

- Track: real-time updates from "preparing" through "delivered"

- Rate and reorder

## Discovery and search

The home feed is the heaviest screen. Components:

- Geocode the user's current location (or a saved address)

- Server returns ranked restaurants within delivery radius

- Personalization: cuisine preferences, past orders, time-of-day signals

- Carousels: "Fast near you", "Sponsored", "New", "Reorder"

Caching strategy: cache the home payload by (location grid cell, time bucket) on the client; refresh stale entries silently in the background. Cell-based caching means thousands of users in the same area share a cache and the server gets fewer requests.

## Cart state

The cart needs to survive app kill, switch to web, and roaming back. Two storage layers:

- Local SQLite/CoreData: source of truth offline; hydrates UI instantly

- Server-backed cart tied to user ID: enables cross-device, web↔app continuity

Sync rule: optimistic local update, debounced PUT to server, conflict-resolve by latest-write-wins per item or merge by union.

## Real-time tracking

The most-watched screen in the app. Status transitions:

- Order placed → confirmed → preparing → courier assigned → picked up → en route → delivered

- ETA estimate refreshed on each transition and on courier location updates

Transport: WebSocket while screen is foregrounded; falls back to silent push for background updates so the app can update notifications without keeping a socket open. Same pattern as Uber rider — see the Uber design doc on this site for the tradeoffs.

## Maps and ETA

Show the courier moving toward the eater. Smooth client-side animation between server samples (linear interpolation between last two known positions). ETA comes from a routing service that knows traffic and the courier's task list (multi-drop trips).

## Payment and tipping

- Apple Pay / Google Pay first; saved cards as fallback

- Tip can be edited until courier picks up — design a small grace window with optimistic update + server validation

- Refund flow for missing items: photo upload, automated triage, instant credit for trusted accounts

## Offline and degraded modes

- Hard offline: show cached menu, disable "Place order" button

- Slow network: skeleton states; do not block on images for the menu render

- Restaurant offline: graceful "Sorry, this restaurant is currently unavailable" without crashing the cart

## Notifications

- Push for each status transition (preparing, picked up, en route, delivered)

- Live Activity (iOS) / Live Update (Android 14+) so users see ETA on the lock screen

- Marketing pushes are separate; respect quiet hours and per-category opt-outs

## Scale considerations

- Search ranking: precomputed at the cell level, refreshed every few minutes; per-user re-rank in a small final step

- Order routing: dispatch service runs on the backend; the app just observes

- Surge / market dynamics: the app shows the price but is not aware of the algorithm

## What separates senior from staff

Junior candidates list features. Senior candidates discuss the cart-sync conflict model and the foreground/background WebSocket-vs-push tradeoff. Staff candidates discuss multi-tenancy of the courier (multi-restaurant multi-drop trips) and how the eater UI represents that without lying about ETA.

## Frequently Asked Questions

### Why split eater and courier into separate apps?

Different UX, different permissions, different background needs. Couriers run a navigation app for hours; eaters need an instant-load home feed. Sharing a binary would compromise both.

### How do I handle scheduled orders?

Same data model with a scheduled_for timestamp. Server enqueues a delayed dispatch. The app shows "Scheduled for 7 PM" prominently so the user is not surprised.

### What about the restaurant tablet?

Out of scope for the eater question, but mention you would design it as a thin client over the order pipeline with a printer integration and noise-tolerant UI.
