SYSTEM_DESIGN
System Design: Review & Rating System
System design of a review and rating system with fraud detection, helpfulness ranking, and aggregated ratings serving millions of product pages.
Requirements
Functional Requirements:
- Users submit text reviews with star ratings (1-5) for purchased products
- Verified purchase badge for reviews from confirmed buyers
- Helpfulness voting: users can mark reviews as helpful or not helpful
- Review sorting: most helpful, most recent, critical first
- Aggregated rating summary: average score, rating distribution histogram
- Photo and video attachments in reviews
Non-Functional Requirements:
- Support 500M reviews across 100M products
- Product page rating display under 50ms (p99)
- Review submission to visibility latency under 5 minutes (includes moderation)
- 99.9% availability for read path; eventual consistency for aggregations
- Fraud detection must catch 95% of fake reviews before publication
Scale Estimation
500M total reviews, 500K new reviews/day = 5.8 reviews/sec write QPS. Product page loads needing ratings: 50M/day = 579 QPS for aggregated ratings. Review list reads: 10M/day = 116 QPS. Each review: ~1KB text + metadata; 500M reviews = 500GB. Images/videos: 20% of reviews have media, averaging 3 images at 200KB = 30TB media storage. Aggregated ratings: 100M products × 100 bytes = 10GB — easily cached entirely in Redis.
High-Level Architecture
The Review & Rating Service separates the write path (submission + moderation) from the read path (display + aggregation). The write path: Review Submission API → Moderation Pipeline (Kafka) → Review Store (PostgreSQL). The Moderation Pipeline runs three stages: (1) Automated content moderation — ML classifier detects spam, profanity, and policy violations; (2) Fraud detection — signals include review velocity, reviewer history, text sentiment vs. star rating mismatch, and seller-reviewer relationship analysis; (3) Manual review queue for borderline cases flagged by ML. Approved reviews are written to PostgreSQL and a Kafka event triggers cache invalidation and rating re-aggregation.
The read path: Product page rating request → Redis cache (stores pre-computed aggregation: average rating, rating distribution, total count) → served in <5ms. Review list request → Elasticsearch (full-text indexed reviews with sorting by helpfulness_score, recency, rating) → paginated response. The aggregation is updated asynchronously: a Kafka consumer listens for review events (new, edited, deleted) and recomputes the product's aggregate rating, writing the result to Redis.
Core Components
Fraud Detection Engine
Fake review detection uses a multi-signal ML model (gradient-boosted trees) scoring each review 0-100 on fraud likelihood. Features: reviewer account age (<30 days = suspicious), number of reviews in last 24 hours (>5 = suspicious), text similarity to other reviews of the same product (cosine similarity >0.8 = copy-paste), star rating deviation from product average (5-star review for a 2-star average product), seller-reviewer purchase pattern (reviewer bought from only one seller repeatedly), and IP/device clustering (multiple reviews from the same IP). Reviews scoring >70 are blocked; 40-70 enter manual review; <40 are published immediately.
Helpfulness Ranking
Review helpfulness is computed using a Wilson score interval — a statistical method that balances the proportion of helpful votes against the total number of votes, accounting for low sample sizes. The formula: (helpful + 1.9208) / (total + 3.8416) - 1.96 * sqrt(helpful * not_helpful / total + 0.9604) / (total + 3.8416). This ensures a review with 10 helpful out of 10 votes doesn't rank above a review with 500 helpful out of 600 votes. The helpfulness score is stored as a materialized field on the review record and recalculated on every vote via a Kafka consumer.
Rating Aggregation Service
Aggregate ratings are pre-computed and cached in Redis as a hash: rating:{product_id} → {avg: 4.3, total: 1247, dist: {1: 45, 2: 78, 3: 124, 4: 389, 5: 611}}. When a new review is published, the aggregation consumer reads the current aggregate from Redis, applies the incremental update (new_avg = (old_avg * old_count + new_rating) / (old_count + 1)), and writes back. For products with >10,000 reviews, full re-aggregation runs nightly from PostgreSQL as a consistency check.*
Database Design
PostgreSQL schema: reviews table (review_id UUID PK, product_id, user_id, rating SMALLINT, title VARCHAR(200), body TEXT, verified_purchase BOOLEAN, helpful_count INT, not_helpful_count INT, helpfulness_score FLOAT, status ENUM('pending', 'published', 'rejected', 'flagged'), media_urls JSONB, created_at, updated_at). Indexes: (product_id, helpfulness_score DESC) for most-helpful sorting; (product_id, created_at DESC) for recency sorting; (user_id, created_at DESC) for user's review history.
Elasticsearch index mirrors the reviews table with additional analyzed text fields for full-text search. The mapping uses a custom analyzer for review text with synonym expansion and language detection. A separate votes table in PostgreSQL: (user_id, review_id, vote ENUM('helpful', 'not_helpful'), created_at) with UNIQUE constraint on (user_id, review_id) to prevent double-voting.
API Design
POST /api/v1/products/{product_id}/reviews— Submit a review; body contains rating, title, body, media_ids; returns review_id with pending statusGET /api/v1/products/{product_id}/reviews?sort=helpful&rating=5&page=1&size=10— Fetch reviews with filtering and sortingGET /api/v1/products/{product_id}/rating-summary— Get aggregated rating (average, distribution, total count); served from RedisPOST /api/v1/reviews/{review_id}/votes— Vote on review helpfulness; body contains vote_type (helpful/not_helpful)
Scaling & Bottlenecks
The rating aggregation hotspot occurs when a viral product receives thousands of reviews in a short period. Each review triggers a Redis read-modify-write cycle. To prevent race conditions, the aggregation update uses Redis MULTI/EXEC transactions with WATCH on the rating key for optimistic locking. For products receiving >100 reviews/minute, updates are batched: a counter rating_pending:{product_id} accumulates new ratings, and a scheduled job flushes them to the aggregate every 10 seconds.
Elasticsearch query performance for products with 100,000+ reviews requires careful index design. Reviews are indexed with product_id as a routing key, ensuring all reviews for a product land on the same shard. This eliminates scatter-gather for product-scoped queries. Shard sizing targets 20GB per shard; products with extreme review counts (>500K) get a dedicated index.
Key Trade-offs
- Wilson score over simple average for helpfulness: Statistically robust ranking that handles low-vote-count bias, but more complex to explain to users and harder to debug
- Async moderation pipeline (5-minute delay): Catches 95% of fake reviews before publication, but delays legitimate reviews — fast-track path for verified purchases with high-reputation accounts reduces perceived delay
- Pre-computed aggregations in Redis over real-time calculation: Sub-5ms rating display on every product page, but introduces eventual consistency — a new review takes 1-2 seconds to affect the displayed average
- Elasticsearch for review search over PostgreSQL full-text: Superior relevance ranking and faceting capability, but adds operational complexity and a synchronization pipeline
GO DEEPER
Master this topic in our 12-week cohort
Our Advanced System Design cohort covers this and 11 other deep-dive topics with live sessions, assignments, and expert feedback.
// RELATED_DESIGNS
System Design: Fraud Detection System
Design a real-time fraud detection system for financial transactions using ML scoring, rule engines, behavioral analytics, and device fingerprinting to block fraudulent payments while minimizing false positives.
System Design: In-Game Purchase System
Design a reliable in-game purchase and virtual economy system supporting real-money transactions, virtual currency, item inventories, and fraud detection at scale for a live-service game.
System Design: ML-based Fraud Detection
Design a real-time ML-based fraud detection system that evaluates transactions in milliseconds, combining rule engines with gradient boosting and neural network models. Covers feature engineering, online learning, explainability, and the feedback loop for model improvement.
System Design: Travel Review Platform
Design a travel review platform like TripAdvisor — covering review ingestion, ranking algorithms, fake review detection, and multi-language content serving.
How to Design a URL Shortener (TinyURL)
Complete system design breakdown of a URL shortener service like TinyURL or Bitly, covering high-level architecture, database design, hash generation, and scaling strategies.
System Design: Instagram
Deep dive into designing Instagram at scale, covering photo/video uploads, feed generation, follower graphs, and CDN strategies used by systems serving 2 billion users.