Design Food Delivery System

Food delivery platform inspired by DoorDash, Uber Eats and Swiggy: geo-filtered restaurant discovery, idempotent orders with a state machine, restaurant tablet push, courier location tracking in a geo store, automatic dispatch, live ETAs and capture-on-delivery payments. A teaching design.

Functional requirements

  • Browse restaurants by cuisine, ratings, distance, and promotions.
  • View real-time menus with pricing, availability, and preparation time.
  • Add/remove items to cart; apply promo codes; compute delivery fees and taxes.
  • Checkout with secure payments; orders must be confirmed within seconds.
  • Automatic courier assignment with batching where possible; live order tracking.
  • Substitutions and out-of-stock handling with customer approval.
  • Order status push notifications and in-app updates across devices.
  • Restaurants receive orders on a partner app or web console with acknowledgment.
  • Cancellations, refunds, and support workflows with audit trails.
  • Order history, re-ordering, and receipts via email.

Non-functional requirements

  • Availability: 99.95% uptime; a single instance or AZ failure must not impact ordering.
  • Performance: catalog/menu reads < 100 ms p99 cache-warm; checkout confirmation < 2 s p99.
  • Scalability: independently scale catalog, checkout, and delivery assignment; handle regional dinner surges.
  • Durability: orders and payments persisted with transactional guarantees; receipts retained per compliance.
  • Consistency: strong consistency for orders/payments; eventual consistency tolerated for analytics and recommendation feeds.
  • Security: PCI-DSS scope isolated to payment service; TLS 1.2+ in transit; AES-256 at rest.
  • Resilience: circuit breakers and timeouts between services; retries with backoff and idempotency keys at checkout.
  • Observability: traces, structured logs, and metrics for API, queue depth, and assignment latency.
  • Geo: latency-based routing at the edge; store-specific menus cached per region.

How the design evolves

Stage 1: Single Server, Couriers Assigned by Phone

See why one server listing everything and manual dispatch can't handle dinner rush.

What was missing: Nothing yet.

Why that's risky: Customers see restaurants that can't deliver to them, a retried order creates a duplicate, nobody knows where couriers are, and dinner traffic swamps one server.

What gets added: One server that lists every restaurant, places orders, and leaves courier assignment to staff.

Trade-offs: Fine for one town and a handful of couriers.

Stage 2: Restaurants Near You and Idempotent Orders

Show only restaurants that deliver to the customer, and never create an order twice.

What was missing: All restaurants were listed and retries duplicated orders.

Why that's risky: After ordering, nothing tells the restaurant or updates the customer.

What gets added: A discovery service backed by a geo index of restaurants and delivery areas, a menu service with a cache, a CDN for photos, and an order service that creates each order in a transaction keyed by an idempotency key.

Trade-offs: Menus are cached, so a sold-out item can show for a moment; the order service rechecks availability.

Stage 3: Order Lifecycle, Restaurant Tablets and Notifications

Move each order through its states and keep restaurant and customer informed.

What was missing: Orders were recorded but nobody acted on them.

Why that's risky: There's still no courier: someone has to find one manually.

What gets added: An order event stream of state changes, a push channel that sends new orders to restaurant tablets and collects 'accepted' and 'ready', and a notification worker that updates customers.

Trade-offs: Notifications follow state changes by a second or two.

Stage 4: Courier Locations and Dispatch

Know where every courier is and assign each order automatically.

What was missing: No courier positions and no automatic assignment.

Why that's risky: Customers can't see where their courier is or when the food will arrive.

What gets added: Couriers' apps send GPS pings to a location service that keeps every online courier in a geo store; a dispatch worker finds nearby available couriers when an order is accepted, picks one by pickup ETA (batching orders heading the same way) and offers the job with a timeout.

Trade-offs: Dispatching when the restaurant accepts (not when the order is placed) avoids couriers waiting at the counter, at the risk of a short wait for a courier.

Stage 5: Live Tracking and ETAs

Show the courier on the map and an honest arrival time.

What was missing: Customers couldn't see progress.

Why that's risky: Payments aren't captured or paid out, and abuse and quality aren't watched.

What gets added: A tracking service showing the courier's live position, and an ETA service predicting prep and travel time from the restaurant's prep history, the courier's position and traffic.

Trade-offs: ETAs are re-estimated as the order progresses rather than fixed at checkout.

Stage 6: Payments, Protection and Monitoring

Charge and pay out correctly, block abuse, and watch delivery quality.

What was missing: Payments weren't captured, and nothing limited abuse or measured service quality.

Why that's risky: Remaining risk is regional: each city's dispatch should keep working if another region fails.

What gets added: A payment worker that captures the payment authorized at checkout once the order is delivered and pays out restaurants and couriers, a rate limiter, and monitoring of order success, dispatch time, acceptance rate and ETA accuracy.

Trade-offs: Capturing on delivery means a cancelled order is never charged, at the cost of rare failed captures.

Frequently asked questions

How do you keep checkout idempotent under retries?

Require an idempotency key from the client for checkout requests. Persist the key with the final order result. On retry, return the stored outcome. Ensure payment capture and order write are idempotent and use outbox/event logs for downstream publication.

How do you assign couriers efficiently during peaks?

Use a delivery service that batches nearby orders and available couriers. Maintain a priority queue by ETA/cost. Use a worker consuming assignment requests from a queue, with backoff and retries for contention. Keep courier location updates in memory for fast lookups.

How do you keep menus fresh without overloading databases?

Cache per-restaurant menus with short TTLs and invalidate on updates from the partner console. Use background refresh for top restaurants during peaks. Include ETags to avoid sending full payloads.

How do you ensure PCI compliance while keeping the system agile?

Isolate payment processing in a dedicated service behind strict network and data access controls. Tokenize card data; never store PANs directly. Use a compliant PSP. Keep the rest of the platform out of PCI scope.

PRISM
System Design Interview
Round 1 of 4 · Architecture Design · 60:00 remaining
PRISM logo PRISM logo
Problems
AI Interview
Interview Challenges
Build & Stress Test NEW
System Architectures
Design & Fix NEW
Interactive Roadmap
System Design Guides Interview Prep Guide
Problems
Today's mission
Notifications
    Theme
    Pricing Community NEW Send feedback Report a problem NEW
    Sign in
    Theme
    Community NEW Send feedback Report a problem NEW
    All problems
    Phase
    Build & Stress Test
    Phase 01: Thinking in Systems
    Upcoming

    Components

    User
    CDN
    Load Balancer
    Server
    Cache
    Database
    Blob Storage
    Search Index
    Queue
    Worker
    Rate Limiter
    Service
    API Gateway
    Reverse Proxy
    WebSocket Server
    Third-party API

    Inspector

    Notes
    Use clear names so your design intent is easy to understand.
    Good
    Name by business meaning
    "Order API", "Restaurant Service"
    Avoid
    Generic names = zero signal
    "Server 1", "API", "Queue"
    A short description for each component makes feedback much better.
    100%
    Start by identifying:
    • Users & entry points
    • APIs & services
    • Databases & storage
    • Traffic flow & scale

    Round 1 of 4 Architecture Design

    Run a simulation to see results.

    Time Remaining
    60:00
    System Design Interview

    What are the core functional requirements?
    What are the key non-functional constraints?

    Questions

    Start Evaluation to unlock questions.

    EVALUATE MODE

    Test yourself like it's the real thing.

    A structured 4-module evaluation that mirrors how top companies assess system design candidates.

    Architecture Design
    Draw your system on the canvas. Define components, connections, and data flow.
    FR & NFR Requirements
    Answer functional and non-functional requirement questions about your design.
    MCQ Round
    Multiple choice questions testing your depth on the chosen system.
    Tradeoff Analysis
    Justify your design decisions and defend your architectural tradeoffs.
    AI Report Generated
    Choose a Problem
    No problem selected
    • 30 min
    • 45 min
    • 60 min
    Round 2 of 4
    MCQ Round
    Answer multiple-choice questions based on your design.

    Exit Interview?

    You're in the middle of an interview session. Leaving now will end your current attempt.

    Your progress will be saved.

    Open a saved design

    Select a design to load into the canvas.

    My Evaluations

    Your past evaluation sessions

    Here’s a simple request flow that follows the expected layer order.

    External User
    →
    Edge CDN → API Gateway → Load Balancer
    →
    Compute App Servers / Services
    →
    DataAccess Cache
    →
    Storage Database / Search Index
    →
    Async Queue → Worker

    Tip: keep arrows moving forward through layers (Edge → Compute → Storage). Avoid sending storage back to compute.

    Evaluation Instructions

    Read the rules carefully before starting. The test auto-submits on refresh.

    Before you start

    • Build your architecture on the canvas. The timer starts when you click Start Evaluation.
    • Don't forget to answer Functional Requirement and Non Functional Requirements.
    • When satisfied with your design, click Next to lock it and view the questions.
    • Please answer final step questions to complete the evaluation.

    Dos

    • Do read each question carefully before answering.
    • Do include required components to maximize component coverage.
    • Do save a copy of your design if you want to keep it before submission.

    Don'ts

    • Don't refresh or close the tab during an active evaluation — this will auto-submit your answers.
    • Don't switch app modes or open another tab while the evaluation is running.
    • Don't attempt to edit the design after clicking Next; the workspace will be locked.

    All the best!!

    Confirm

    Input

    Notice

    Evaluation Report
    Report a problem

    Evaluation Complete

    Generating Your Report

    Hang tight — our AI is evaluating your design…

    Did you know?

    Loading…

    Share feedback

    Tell us what worked well and what we can improve.

    Let's personalize this

    Answer a couple of quick questions so we can tailor your journey and missions.

    Your welcome gift: of Full PRISM Access

    Your Pro access starts as soon as you press Start my journey.

    SYSTEM BRIEF

    System Constraints

    What the system must do — every item is a user-facing behaviour your architecture must support.

      ↑ Engineering Constraints

      These are the failure modes you must design against — latency SLAs, durability targets, traffic ceilings.

        ⇆ Architecture Constraints

        Core Concepts to Master

        Your Journey
        PHASE – –
        0 / 0 0%
        0
        Mock Interview Checklist

        Pick a topic to start

        Explore concept overviews, real-system examples, key tradeoffs, and interview talking points for each roadmap section.

        Phase Mastered

        You've conquered this phase. These are the skills you now own:

          +500 XP

          Company Interview Paths

          Progress Summary