System Design 6: Design Food Delivery Application like Zomato / Swiggy / Uber Eats (HLD & LLD)
Designing a hyper-local food delivery marketplace requires coordinating three distinct actors—Users, Restaurants, and Delivery Agents—in real-time across high-concurrency distributed systems. This comprehensive study note details the functional requirements, non-functional constraints, API designs, and a robust microservices architecture featuring event-driven messaging, geospatial indexing, and real-time state tracking.
1. Why Do We Need This? (Problem Statement & Status Quo)
Modern on-demand food delivery platforms must bridge the physical and digital worlds instantly. Users expect to open an app, browse hundreds of nearby restaurants within a 5-10 km radius, customize menus, place secure payments, and track their delivery drivers live on a map down to the second.
Building a monolithic architecture for this scale leads to catastrophic bottlenecks. Because different components have vastly different throughput and consistency profiles (e.g., browsing menus vs. processing financial transactions), the system must be decoupled into independent, highly scalable microservices.
2. Core Mental Model & Real-Life Analogy
Real-Life Analogy: The Central Dispatch Hub
Think of a food delivery application as a bustling central delivery exchange:
- The Menu Catalog (The Restaurant's Catalog): Comparable to physical paper menus handed out by restaurants, dynamically indexed so customers can quickly search for items like "Chicken Biryani" without flipping through thousands of pages.
- The Cart & Checkout (The Cashier Counter): Enforces strict separation—you cannot mix items from two different restaurants into the same active transaction.
- The Dispatcher (Delivery Matching Service): Acts like a head dispatcher at a courier station who scans a map for idle couriers sitting closest to a specific restaurant and broadcasts order pickups.
3. Functional Requirements
During a system design interview, scope the feature set clearly. For a production-grade food delivery service, the core functional requirements include:
- User Authentication: Secure sign-up, login, logout, and profile updates.
- Nearby Restaurant Discovery: Display open restaurants within a configurable geographic radius (e.g., 5-10 km) based on the user's current latitude and longitude.
- Catalog & Menu Search: Search for specific restaurants or food items via a search bar (matching titles and food categories).
- Restaurant Detail & Menus: Fetch metadata and available food items for a selected restaurant.
- Cart Management: Add, update, or remove items (with specific quantities) tied to a single restaurant context.
- Checkout & Payment: Place orders and process secure transactions via a payment gateway.
- Restaurant Order Acceptance: Restaurants receive pending orders, accept or reject them, and trigger food preparation tracking.
- Driver Allocation: Automatically assign an idle nearby delivery agent once the restaurant accepts the order.
- Real-Time Order Tracking: Stream live geographical updates of the delivery partner to the user via WebSockets.
4. Non-Functional Requirements & CAP Theorem Strategy
System Scale & Assumptions
- Global Active Users: ~50 million users.
- Registered Restaurants: ~1 million restaurants worldwide.
- Concurrency: High peak traffic during lunch and dinner hours.
CAP Theorem Trade-offs in Microservices
Because we operate a distributed microservice architecture, we must apply the CAP Theorem strategically across different modules:
5. Core Entities Identification
From the functional requirements, we derive five foundational domain entities:
- User: Metadata, credentials, and delivery addresses.
- Restaurant: Profile, location coordinates, operating status, and media assets.
- Food Menu / Item: Categorized dishes linked to specific restaurants with pricing and descriptions.
- Delivery Agent (Driver): Real-time GPS coordinates, availability status, and active task assignments.
- Payment: Transaction records, gateway tokens, and financial ledgers.
6. Public API Design (REST Endpoints)
API endpoints map directly to user-facing functional requirements.
User & Authentication
POST /api/v1/users/register- Onboard a new user.POST /api/v1/users/login- Authenticate and return a JWT token.PUT /api/v1/users/{id}- Update user profile and address metadata.
Restaurant Discovery & Search
GET /api/v1/restaurants/nearby?lat={lat}&lon={lon}&radius={radius}- Retrieve paginated restaurant IDs and thumbnails within a given radius.GET /api/v1/restaurants/search?query={searchTerm}&lat={lat}&lon={lon}- Search restaurants and food items matching a query.GET /api/v1/restaurants/{restaurantId}- Fetch full restaurant metadata.GET /api/v1/restaurants/{restaurantId}/menu- Retrieve available food items and categories.
Cart & Ordering
POST /api/v1/cart- Add an item and quantity to the active cart (requiresrestaurantIdanditemId).PUT /api/v1/cart/{cartId}- Update item quantities.DELETE /api/v1/cart/{cartId}- Clear or remove items from the cart.POST /api/v1/orders- Submit checkout and invoke payment processing, returning anorderId.
Tracking
GET /api/v1/orders/{orderId}/track- Retrieve current dispatch status and delivery partner metadata.
7. High-Level Architecture & Component Flow
The high-level design cleanly separates concerns across the three core actors: Users, Restaurants, and Delivery Agents.
Core Services Breakdown:
- API Gateway & Load Balancer: Handles SSL termination, round-robin load distribution, rate limiting, and JWT authentication/authorization.
- User Service: Manages customer profiles and authentication against MySQL/PostgreSQL.
- Search Service: Indexes restaurant menus and locations using Elasticsearch for sub-second keyword and geo-queries.
- Cart Service: Maintains isolated shopping carts per restaurant in relational storage.
- Order Service: Coordinates checkout workflows, communicating with payment gateways and event brokers.
- Restaurant Service: Manages restaurant metadata, operating hours, and catalog uploads.
- Delivery Matching Service: Evaluates spatial proximity to pair accepted orders with idle drivers.
- Location Update Service: Ingests high-frequency ping data from delivery agents.
8. Low-Level Design (LLD) & Deep Dive Component Analysis
A. User Service & Database Schema
The user database is a relational MySQL/PostgreSQL store holding account credentials and saved delivery addresses.
CREATE TABLE users (
user_id BIGINT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
phone_number VARCHAR(20) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
B. Search Service & Elasticsearch Integration
To provide lightning-fast searches across 1 million restaurants and millions of menu items, we use Elasticsearch.
- Blob Storage (S3): Restaurant banners, food photos, and promotional graphics are stored in an S3-compatible object store. Database records store only the S3 URL string.
- CDC (Change Data Capture): When restaurant owners update menus in PostgreSQL, a CDC pipeline (e.g., Debezium) streams changes to sync documents in Elasticsearch.
CREATE TABLE restaurants (
restaurant_id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(150) NOT NULL,
address TEXT NOT NULL,
status ENUM('OPEN', 'CLOSED', 'MAINTENANCE') DEFAULT 'OPEN',
latitude DECIMAL(10, 8) NOT NULL,
longitude DECIMAL(11, 8) NOT NULL,
images_json JSON -- Array of S3 URLs
);
CREATE TABLE menus (
menu_id BIGINT PRIMARY KEY AUTO_INCREMENT,
restaurant_id BIGINT NOT NULL,
title VARCHAR(100) NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL,
category VARCHAR(50),
image_url VARCHAR(255),
FOREIGN KEY (restaurant_id) REFERENCES restaurants(restaurant_id)
);
C. Cart Service Isolation
Cart DB enforces restaurant segregation so users cannot mix food items from multiple vendors.
CREATE TABLE carts (
cart_id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
restaurant_id BIGINT NOT NULL,
items_json JSON NOT NULL, -- [{ itemId, quantity, price }]
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
D. Order Placement & Event-Driven Architecture (Kafka)
Because order processing triggers multiple asynchronous side-effects (payment processing, updating inventory, notifying restaurants, and assigning drivers), we use Apache Kafka as an event broker.
CREATE TABLE payments (
payment_id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
order_id BIGINT NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
currency VARCHAR(3) DEFAULT 'USD',
status ENUM('SUCCESS', 'FAILED', 'PENDING') NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE orders (
order_id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
restaurant_id BIGINT NOT NULL,
driver_id BIGINT DEFAULT NULL,
total_amount DECIMAL(10, 2) NOT NULL,
status ENUM('CREATED', 'PAID', 'ACCEPTED', 'PREPARING', 'READY', 'DISPATCHED', 'DELIVERED', 'CANCELLED') NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
E. Driver Location Tracking & Proximity Matching (Redis + Geohash)
Delivery agents ping their GPS coordinates every 5–10 seconds. Writing millions of frequent writes directly to a relational database creates massive I/O bottlenecks.
- Ingestion Flow: Driver pings hit a Kafka Gateway (
driver-location-topic). - Fast Write Cache: A consumer service updates a Redis Cluster in-memory cache to maintain near real-time positions with a TTL (Time-To-Live) of 10-15 seconds. If a driver loses connection and stops pinging, the TTL expires, marking them offline.
- Geohashing & Proximity: The Delivery Matching Service uses Geohash algorithms against Redis geospatial indexes to identify idle drivers within a close radius of the restaurant.
F. Real-Time WebSocket Delivery Updates
Once an order is picked up by a delivery partner, users expect live map tracking.
- WebSocket Gateway & Manager: Opening persistent WebSocket connections is memory-intensive. A dedicated WebSocket Manager efficiently handles persistent connections.
- Live Broadcast: As drivers stream coordinate updates, the WebSocket Manager pushes location payloads directly to the customer's browser or mobile app.
9. Summary and Key Takeaways
- Modular Requirements Gathering: System design interviews for applications like Zomato/Swiggy span multiple actors (Users, Restaurants, Drivers); always clarify scope with your interviewer early.
- Strategic CAP Theorem Application: Use AP architectures for Search & Discovery to maximize availability, and CP architectures for Cart, Checkout, and Payments to guarantee financial consistency.
- Elasticsearch for Geospatial Search: Combine Elasticsearch with PostgreSQL and S3 blob storage to handle complex textual restaurant searches and rich image catalogs.
- Event-Driven Decoupling with Kafka: Isolate critical side-effects during checkout (payment confirmation, restaurant alerts, order status updates) using Kafka messaging topics.
- In-Memory Scale with Redis: Handle high-frequency driver GPS pings (every 5-10 seconds) using Redis caching with TTL expiration rather than hammering relational databases.
- Real-Time Tracking via WebSockets: Implement persistent WebSocket gateways to stream live delivery partner coordinates to users once orders are dispatched.