Design a Food Review and Voting System
DoorDashSoftware Engineer · OnsiteLast updated
Design a scalable review and voting platform for dishes and restaurants, focusing on transactional vote changes, aggregate counter consistency, hot-item read/write scaling, and stable pagination.
Scenario
Design a customer review and voting platform for an on-demand food delivery service. Customers can submit ratings (1–5 stars) and written reviews for menu items or restaurants. Other users can vote on whether a review was "helpful" or "unhelpful". Each user may have at most one active vote per review (upvote, downvote, or neutral/retracted).
Requirements
Functional Requirements
- Review Creation & Management: Users can create, update, and delete reviews for restaurants or menu items after completing an order.
- Voting: Users can upvote, downvote, or retract their vote on a review. Switching from upvote to downvote must correctly adjust aggregate totals.
- Feed & Retrieval: Users can fetch paginated reviews for a store or dish sorted by helpfulness (net score), recency, or star rating.
- Aggregate Ratings: Display aggregated review counts, average star ratings, and helpfulness metrics on restaurant/dish pages.
- Moderation: Support flagging reviews for inappropriate content and immediately suppressing them from public view.
Non-Functional Requirements & Scale
- Scale: 50 million Daily Active Users (DAU); 500 million total reviews; 2 billion total votes.
- Traffic: 100:1 read-to-write ratio. Peak read traffic reaches 50,000 queries per second (QPS) across restaurant pages. Highly popular restaurants experience intense read and voting spikes.
- Consistency & Latency: P99 read latency < 50ms. User vote updates must feel immediate to the voter (read-your-own-writes), while global aggregate counts can be eventually consistent within 1–2 seconds.
- Reliability: Aggregate counters must not permanently drift over time due to network partitions, duplicate requests, or race conditions.
What to Cover
- API Design: Define the core endpoints for submitting reviews, mutating votes, and fetching review feeds.
- Data Model: Schema design for reviews, user vote states, and aggregate stats.
- Concurrency & Voting Invariants: How to enforce one-vote-per-user-per-review and handle rapid vote flips without race conditions.
- Hot-Entity Scaling: Architectural strategies to handle viral restaurants and disproportionately popular reviews.
- Pagination & Consistency: Efficient pagination across dynamic ranking scores and an aggregate repair mechanism to fix counter drift.
Hints
Hint 1
Model user votes as a distinct state table with a unique composite key on `(user_id, review_id)` to enforce the single-vote invariant and calculate the exact delta for vote flips.
Hint 2
Decouple hot counter updates from the primary transaction using an in-memory buffer or a distributed stream (like Kafka) with write batching to absorb voting bursts.
Hint 3
Avoid offset-based pagination on dynamically sorted metrics; use cursor-based pagination on a composite index like `(net_helpful_score, review_id)` or cache precomputed top-N reviews for hot items.
Follow-up questions
- How would you handle write contention when millions of users vote on the top review of a viral restaurant within a short time window?
- How does your system detect and repair drift between the aggregate helpful counts and the actual rows in the vote state table without taking tables offline?
- What strategies would you employ to detect and mitigate coordinated vote manipulation or review bombing campaigns?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.