Hide sidebar

Design Yelp

Design Yelp
Medium
Yelp is a crowd-sourced review platform for businesses. Users can search for local businesses, read and write reviews, and see ratings. This design will focus on the core features: searching for businesses, submitting reviews, and aggregating ratings.

Variants:

Google MapsTripAdvisorFoursquare

High-Level Design

Loading diagram...

Yelp System Design Requirements

Functional Requirements

1

Business Search

Users should be able to search for businesses by keyword, location, and category.

2

Reviews and Ratings

Users should be able to read reviews and ratings for businesses, and submit their own reviews and ratings.

3

Business Listings

The system should display detailed information about businesses, including address, photos, and user reviews.

Non-Functional Requirements

1

High Availability

The platform must be highly available to users for searching and to businesses for managing their listings.

2

Low Latency Search

Search results must be returned quickly (e.g., under 200ms) to provide a good user experience.

3

Data Consistency

While some eventual consistency is acceptable (e.g., for new reviews appearing in search), the average rating for a business should be updated in near real-time after a new review is submitted.

CAP Theorem Trade-offs

ConsistencyAvailabilityPartition Tolerance
Trade-off Explanation:

Yelp leans towards Consistency and Availability. While search results can be eventually consistent, it's important for review and rating data to be as up-to-date as possible. The system must remain available for users to search and read reviews.

Scale Estimates

User Base100M users (10^8)
Base assumption for system sizing
Search Queries per Second10,000 qps
Peak search queries per second the system must handle.
Total Businesses20M
Total Reviews200M

API Design

GET/api/businesses/search

Search for businesses by term, location, and category.

Request Body

{ "term": "string", "location": "string", "category": "string" }

Response Body

[{ "business_id": "string", "name": "string", "rating": 4.5, "review_count": 123 }]
GET/api/businesses/{business_id}

Get detailed information for a specific business.

Response Body

{ "business_id": "string", "name": "string", "address": "string", "reviews": [...] }
POST/api/reviews

Submit a review for a business.

Request Body

{ "user_id": "string", "business_id": "string", "rating": 5, "text": "string" }

Response Body

{ "review_id": "string", "status": "success" }

Database Schema

Our database needs to store information about businesses, user reviews, and potentially location data. A relational database like PostgreSQL could work, but a NoSQL database like DynamoDB might be better for handling the scale of user-generated content. The diagram shows a primary database and a separate Elasticsearch index for searching.

Business

business_id
stringPartition Key
name
string
description
string
address
string
location
lat/long
category
string
avg_rating
float
num_ratings
int

Reviews

review_id
stringPartition Key
user_id
string
business_id
stringGSI Key
rating
int
text
string
created_at
timestamp

Locations

location_id
stringPartition Key
name
string
type
string
points
list

Business and Review Services

The core logic of our application is split between two main microservices, as shown in the architecture diagram. This separation of concerns allows for independent development, scaling, and deployment.

Business Service: This service is the definitive source of truth for all business-related information. Its responsibilities include:

  • CRUD Operations: Handling the creation, reading, updating, and deletion of business profiles.
  • Data Ownership: It owns the Business table in our primary database. Any other service that needs business information must query this service's API.
  • Data Enrichment: It could be responsible for background jobs that enrich business data, such as fetching photos from an external API or standardizing addresses.

Review Service: This service manages all aspects of user reviews and ratings.

  • Review Submission: It exposes an endpoint for users to submit new reviews, which includes a star rating and text content.
  • Rating Aggregation: A critical function of this service is to update the overall rating of a business whenever a new review is submitted. As the diagram indicates, this is a synchronous operation. When a review is saved to the Reviews table, the Review Service immediately recalculates the avg_rating and increments the num_ratings in the Business table for the corresponding business. This ensures that the rating displayed to users is always strongly consistent.
  • Trade-offs: While synchronous updates provide immediate consistency, they can introduce latency to the review submission process and create a tight coupling between the Review and Business services. An alternative approach would be to use a message queue. The Review Service would publish a "review_added" event, and a separate worker process would consume this event to update the business rating asynchronously. This would improve the responsiveness of the review submission endpoint at the cost of a slight delay (eventual consistency) in the rating update.

Search and Geospatial Indexing

A powerful and flexible search experience is at the heart of Yelp. Users expect to find businesses by name, category, location, and keywords within reviews. A standard relational database query would be far too slow and inflexible for this. We need a dedicated search index. Here are two potential solutions for this problem.

1

Elasticsearch (Recommended)

Elasticsearch is a distributed search and analytics engine built on top of Apache Lucene. It is the ideal solution for Yelp's needs because it natively supports all the required query types in a single, scalable system.

  • Full-Text Search: It uses an inverted index to provide fast, relevance-ranked results for keyword searches across business names, descriptions, and user reviews.
  • Geospatial Queries: It has robust support for geo_point and geo_shape data types, allowing for efficient queries like "find all cafes within a 1-mile radius" or "find all parks in this neighborhood."
  • Faceted Search & Aggregations: Elasticsearch makes it easy to implement the filters (category, price, rating) that are crucial to the Yelp experience. It can quickly aggregate data to show, for example, the count of businesses in each category that match a search query.
  • Integration: As shown in the diagram, we can keep Elasticsearch synchronized with our primary database using a Change Data Capture (CDC) pipeline. Tools like Debezium can monitor our database's transaction log and stream any changes to a Kafka topic, which then feeds into Elasticsearch. This keeps our search index up-to-date without burdening our application services.
2

Geohashing + Custom Index

If we wanted to build a more custom solution without relying on a comprehensive search engine like Elasticsearch, we could combine multiple technologies.

  • Geospatial Search: We could use the Geohashing technique, as discussed in the Uber system design. Each business's location would be converted into a geohash string, and we would store this in our database (e.g., DynamoDB or PostgreSQL). To find nearby businesses, we would query for all businesses whose geohash shares a common prefix with the user's location's geohash.
  • Text Search: For full-text search on reviews and business names, we would need a separate index. We could use a simpler text search library or a managed service, but we would be responsible for building and maintaining the index ourselves.
  • Complexity: While this approach is feasible, it forces us to manage and scale two separate indexing systems (one for geo, one for text). The complexity of combining results from these different systems makes Elasticsearch a much more practical and powerful choice for a feature-rich application like Yelp.

Complete Design

Loading diagram...

Putting it all together, the Yelp system relies on a service-oriented architecture. The client interacts with an API Gateway, which routes requests to the appropriate microservice (Business or Review). The services interact with a primary database for transactional data. For the complex search requirements, data is replicated to an Elasticsearch cluster via a Change Data Capture pipeline, allowing for fast and flexible searching without impacting the performance of the primary database.