Bird
Raised Fist0

Design a Food Delivery System - Restaurant Discovery, Order Tracking, Driver Assignment

HLDhardInterview freq: high
Choose your preparation mode4 modes available
🎯
Design a Food Delivery System - Restaurant Discovery, Order Tracking, Driver Assignment
45 min · senior
senior

You are designing a food delivery platform serving 50 million daily active users (DAU). The system must support real-time restaurant discovery, order placement and tracking, and efficient driver assignment. The platform requires end-to-end encryption of sensitive user data, offline support for drivers with intermittent connectivity, and must maintain a P99 latency under 200ms for user-facing APIs. The system should handle peak loads of up to 1 million concurrent orders and 500K active drivers.

  • End-to-end encryption of user and payment data is mandatory to comply with privacy regulations.
  • Driver app must support offline mode with eventual sync due to intermittent network connectivity.
  • P99 latency for all user-facing APIs must be under 200ms to ensure smooth UX.
  • System must handle peak load of 1 million concurrent orders and 500K active drivers.
  • Real-time order tracking requires sub-second updates to users and drivers.
  • Data consistency for order status must be strong to avoid double assignments or lost orders.
📋
Guided Steps
1/5
Step 1
Designing Restaurant Discovery Service
How would you design the restaurant discovery feature to support 50M DAU with low latency and rich filtering?
💡 Hint
Consider geo-spatial indexing and caching strategies for fast queries.
Use Elasticsearch with geo_point fields for location-based search and filtering, combined with Redis caching for hot queries to achieve sub-100ms query latency.
Mid: Names Elasticsearch for search. Senior: Explains geo_point indexing, shard strategy for 50M DAU, and Redis TTL caching to reduce ES load.
⚠️Common Wrong Answer
Using a relational database with LIKE queries for location filtering - leads to high latency and poor scalability at 50M DAU.
Step 2
Order Placement and Tracking Architecture
How would you design the order placement and real-time tracking system ensuring strong consistency and P99 < 200ms latency?
💡 Hint
Think about event sourcing, message queues, and state stores for order status updates.
Use Apache Kafka with order_id as partition key for ordered event streams, backed by Cassandra for order state storage, and WebSocket-based push notifications for real-time client updates.
Mid: Mentions Kafka for messaging. Senior: Explains partition key choice for ordering, Cassandra's LSM-tree write scalability, and WebSocket for sub-second updates.
⚠️Common Wrong Answer
Polling order status via REST every few seconds - causes excessive load and fails P99 latency under peak.
Step 3
Driver Assignment and Offline Support
How would you design driver assignment to ensure no double assignments and support offline driver app usage?
💡 Hint
Consider distributed locking and local state sync mechanisms.
Use Redis with Redlock algorithm for distributed locking during assignment to prevent double booking, and implement local SQLite storage on driver app with periodic sync via gRPC when online.
Mid: Names Redis for locking. Senior: Explains Redlock's quorum-based locking guarantees and offline-first local DB with conflict resolution on sync.
⚠️Common Wrong Answer
Assigning drivers without distributed locks - leads to race conditions and double assignments.
Step 4
Ensuring Data Security and Encryption
How would you ensure end-to-end encryption of sensitive data while maintaining system performance?
💡 Hint
Think about encryption at rest, in transit, and client-side encryption.
Implement client-side encryption for sensitive fields using libsodium, TLS 1.3 for in-transit encryption, and AWS KMS-managed keys for server-side encryption at rest in S3 and Cassandra.
Mid: Mentions TLS and encryption at rest. Senior: Details client-side encryption trade-offs, key management with AWS KMS, and performance impact mitigation.
⚠️Common Wrong Answer
Relying only on TLS without encryption at rest or client-side encryption - risks data exposure if servers are compromised.
Step 5
Scaling and Monitoring for Peak Loads
How would you design the system to handle peak loads of 1 million concurrent orders and 500K active drivers with P99 < 200ms?
💡 Hint
Consider autoscaling, backpressure, and observability tools.
Use Kubernetes with Horizontal Pod Autoscaling for microservices, Kafka backpressure mechanisms, and Prometheus + Grafana for real-time monitoring and alerting on latency and error rates.
Mid: Mentions autoscaling and monitoring. Senior: Explains autoscaling thresholds, Kafka consumer lag monitoring, and alerting on SLA breaches.
⚠️Common Wrong Answer
Static provisioning without autoscaling - leads to outages or degraded latency during spikes.
🔌
API Design Challenge
Sketch 3 core RESTful API endpoints for the Food Delivery System covering restaurant discovery, order placement/tracking, and driver assignment.
  • How does the client query and filter restaurants efficiently?
  • How does the client place an order and receive real-time status updates?
  • How does the system assign drivers and confirm assignment to both parties?
📊
Scoring Rubric
▼ Show
Must Have - 60%
  • Use Elasticsearch geo_point indexing for restaurant discovery to meet latency at 50M DAU.
  • Kafka with order_id partition key for ordered event streams and strong consistency in order tracking.
  • Redis Redlock for distributed locking to avoid double driver assignments.
  • Client-side encryption combined with TLS and KMS for end-to-end data security.
  • WebSocket-based real-time updates to meet sub-second order tracking latency.
Good to Have - 30%
  • Redis caching layer to reduce load on search and improve response times.
  • Local SQLite on driver app for offline support and eventual sync.
  • Kubernetes autoscaling and Prometheus monitoring for handling peak loads.
  • gRPC for efficient driver app sync and communication.
Bonus - 10%
  • Detailed failure mode analysis of distributed locking under network partitions.
  • Trade-off discussion on consistency vs availability in driver assignment.
  • Security threat modeling for encryption key management.
pattern: HTTP polling
consequence: At 50M DAU, HTTP polling causes 50 million reconnects per minute just to check for messages, which collapses the system under load.
pattern: Assigning drivers without distributed locks
consequence: Leads to race conditions causing double assignments and inconsistent order states.
pattern: Relying only on TLS without encryption at rest or client-side encryption
consequence: Risks data exposure if servers are compromised, violating privacy regulations.
pattern: Static provisioning without autoscaling
consequence: Causes outages or degraded latency during traffic spikes due to insufficient resources.
pattern: Using relational DB LIKE queries for geo filtering
consequence: Results in high latency and poor scalability at 50M DAU, failing latency SLAs.
✅
Model Answer
▼ Reveal

The Food Delivery System is designed to handle 50 million DAU with strict latency and security requirements. It uses Elasticsearch with geo_point indexing and Redis caching for fast restaurant discovery. Order placement and tracking leverage Kafka with order_id partitioning, Cassandra for state storage, and WebSocket for real-time updates. Driver assignment uses Redis Redlock for distributed locking and local SQLite on driver apps for offline support with gRPC sync. Security is ensured via client-side encryption with libsodium, TLS 1.3, and AWS KMS-managed keys. The system scales with Kubernetes autoscaling and is monitored with Prometheus and Grafana.

  • Use Elasticsearch geo_point fields and shard strategy to support 50M DAU with sub-100ms query latency.
  • Implement Redis caching with TTL to reduce Elasticsearch load for popular queries.
  • Partition Kafka topics by order_id to guarantee ordered event processing and strong consistency.
  • Store order state in Cassandra for high write throughput and linear scalability using LSM-tree storage.
  • Use WebSocket connections to push real-time order status updates to clients and drivers with sub-second latency.
  • Apply Redis Redlock distributed locking to prevent double driver assignments under concurrency.
  • Enable offline support on driver apps with local SQLite DB and periodic sync via gRPC when online.
  • Encrypt sensitive data client-side using libsodium before transmission and storage.
  • Use TLS 1.3 for secure in-transit communication and AWS KMS for key management and encryption at rest.
  • Deploy microservices on Kubernetes with Horizontal Pod Autoscaling and monitor system health with Prometheus and Grafana.
  • Elasticsearch with geo_point indexing for efficient location-based restaurant discovery queries.
  • Redis caching layer with TTL to reduce load on Elasticsearch and improve latency for popular queries.
  • Apache Kafka with order_id partition key to guarantee ordered event processing for order state changes.
  • Cassandra as the order state store for high write throughput and linear scalability with LSM-tree storage.
  • WebSocket connections for real-time order status push notifications to clients and drivers.
  • Redis with Redlock distributed locking to prevent double driver assignments under concurrency.
  • Local SQLite database on driver app for offline order and assignment state with eventual sync via gRPC.
  • Client-side encryption using libsodium to protect sensitive data before transmission and storage.
  • TLS 1.3 for secure in-transit communication between clients, services, and databases.
  • Kubernetes Horizontal Pod Autoscaling and Prometheus monitoring to maintain P99 latency under 200ms at peak load.

Practice

(1/5)
1. In the digital wallet system's transaction processing flow, at Step 4 the Ledger Service applies the debit and credit entries. What happens if the Ledger Service detects a mismatch in the double-entry records at this step?
easy
A. The Ledger Service retries the transaction indefinitely until the entries match
B. The Ledger Service marks the transaction as failed and triggers an alert for manual reconciliation
C. The Ledger Service ignores the mismatch and commits the debit entry only
D. The Ledger Service rolls back the entire transaction and deletes all related entries

Solution

  1. Step 1: Understand Ledger Service's double-entry validation

    The Ledger Service enforces double-entry consistency; mismatches indicate data corruption or bugs.
  2. Step 2: Evaluate failure handling

    Retrying indefinitely (A) risks blocking; ignoring mismatch (C) breaks accounting; deleting entries (D) risks data loss. Marking failed and alerting (B) enables safe manual reconciliation.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Mismatch triggers failure mark and alert -> safe reconciliation [check]
Hint: Mismatch triggers failure mark and alert, not silent retry [OK]
Common Mistakes:
2. A typeahead system must handle millions of concurrent prefix queries with low latency and high throughput. Which component is best suited to serve these prefix lookups efficiently at scale?
easy
A. A distributed in-memory Trie cache sharded by prefix hash
B. A message queue to buffer prefix queries before processing
C. A full-text search engine like Elasticsearch without caching
D. A relational database with indexed LIKE queries on the prefix column

Solution

  1. Step 1: Identify prefix lookup requirements

    Prefix queries require fast, low-latency lookups optimized for string prefixes, which relational DB LIKE queries are inefficient at scale.
  2. Step 2: Evaluate component suitability

    A distributed in-memory Trie cache supports efficient prefix matching and can be sharded by prefix hash for scalability, unlike message queues or full-text search without caching.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Distributed Trie cache -> efficient prefix lookups at scale [check]
Hint: Trie caches excel at prefix queries, unlike DB LIKE or queues [check]
Common Mistakes:
3. You must design a high-throughput OLTP system that requires strong consistency but can tolerate some delay in durability guarantees. Which approach is best suited?
medium
A. Use asynchronous replication with strict serializable isolation but delayed durability
B. Use synchronous replication with immediate durability on commit
C. Use eventual consistency with snapshot isolation and immediate durability
D. Use read uncommitted isolation with synchronous durability

Solution

  1. Step 1: Analyze consistency and durability trade-offs

    Strong consistency requires strict serializable isolation; durability can be delayed to improve throughput.
  2. Step 2: Evaluate replication and isolation options

    Asynchronous replication with strict serializable isolation fits the requirement, allowing durability delay without sacrificing consistency.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Async replication + strict serializable -> strong consistency, delayed durability [check]
Hint: Strong consistency needs strict isolation, durability can lag [check]
Common Mistakes:
4. If the Layer 7 load balancer's HTTP header inspection module fails, what is the most likely failure mode for incoming requests?
medium
A. Requests are forwarded blindly to a default backend without routing based on URL
B. The load balancer drops all TCP connections silently without response
C. The load balancer falls back to Layer 4 forwarding, preserving source IP but ignoring HTTP routing
D. The load balancer encrypts requests incorrectly causing backend decryption errors

Solution

  1. Step 1: Understand failure impact on Layer 7 inspection

    If HTTP header inspection fails, the load balancer may fallback to Layer 4 forwarding to maintain availability.
  2. Step 2: Eliminate options inconsistent with graceful degradation

    Dropping all connections (B) is unlikely; forwarding blindly to default backend (A) loses load distribution; encryption errors (D) unrelated.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Layer 7 failure -> fallback to Layer 4 forwarding without HTTP routing [check]
Hint: Layer 7 fail -> fallback to Layer 4 forwarding [check]
Common Mistakes:
5. For a chat application requiring strict message ordering per conversation and high availability, which design choice is best?
medium
A. Partition messages by conversation ID to preserve order within conversations and replicate partitions for availability
B. Use a single global partition for all messages to preserve total order
C. Use multiple partitions with random keys to maximize throughput, ignoring ordering
D. Use a relational database with row-level locking to enforce ordering

Solution

  1. Step 1: Analyze ordering and availability needs

    Single global partition (A) preserves total order but limits throughput and availability; random keys (C) break ordering; relational DB with locking (D) is a bottleneck at scale.
  2. Step 2: Partition by conversation ID

    Partitioning by conversation ID (B) ensures ordering within conversations and allows replication for availability and scaling.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Partition by conversation ID preserves order and supports availability [check]
Hint: Partition by conversation ID for order and availability [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard