Design Tinder (Dating App / Recommendation)
DifficultyMedium | HelloInterview: problem breakdown
Problem Statement
Design a dating app where users see a deck of profiles, swipe left (reject) or right (like), and are notified when there's a mutual match.
๐Real-world: Two things make Tinder a sharp design. First, the match problem is deceptively about write efficiency โ a "match" is just detecting that two one-way likes point at each other, so you store likes and check for the reciprocal on each swipe (you don't scan; you look up "does B already like A?"). Second, the deck is precomputed โ you don't run an expensive geo + preference query on every swipe; you build a candidate pool ahead of time using a geospatial index (geohash) plus filters. The security/privacy lessons here are real and well-documented: Tinder shipped for years transmitting photos over plain HTTP and leaking exact distances so precise that researchers trilaterated users' locations to within meters ("Tinder Online" / trilateration attacks). The takeaway for this audience: location data is sensitive PII โ fuzz/round distances server-side, never expose precise coordinates to the client, and encrypt everything in transit. Dating apps are a recurring case study in privacy-by-design failures.
Requirements
Functional
- User profile with photos and bio
- Swipe left/right on suggested profiles
- Match when both users like each other
- In-app messaging after match
- Recommendation engine (who to show)
Non-Functional
- 75M DAU, 1.6B swipes/day โ 18,500 swipes/s
- Deck load latency: < 200ms
- Match notification: real-time (< 1s after mutual like)
- Location-based: users see people nearby
Core Design
Profile Deck Generation
The "deck" is a pre-computed list of candidate profiles for each user.
Deck generation factors:
- Location: within X km (geohash query)
- Age range
- Gender preference
- Not already seen (swiped on)
- Scored by recommendation model (photos, activity, compatibility)Pre-computationgenerating a deck in real-time is expensive. Pre-compute each user's deck hourly and cache in Redis.
Redis: deck:{user_id} โ list of profile_ids (sorted by score)
TTL: 1h (refresh hourly or on explicit refresh)Swipe Recording
swipes(
user_id UUID,
target_id UUID,
direction ENUM('like', 'pass'),
created_at TIMESTAMP
)
INDEX (user_id, target_id) -- for "did user A already swipe on user B?"18,500 swipes/s โ Cassandra for write throughput. Partition by user_id.
Match Detection
On "like":
1. Write like to swipes table
2. Check: did target_id already like user_id?
โ SELECT FROM swipes WHERE user_id=target_id AND target_id=user_id AND direction='like'
3. If yes: create match record, notify both usersOptimization: use Redis bloom filter or in-memory set to check if the reverse like exists before hitting the DB.
Match notification: WebSocket push to both users.
Architecture
API โ Swipe Service โ Cassandra (swipes)
โ
Match Checker โ Redis (already liked?) โ Match DB
โ
Notification Service (WebSocket)
Recommendation:
Location Index (Redis/Elasticsearch geo) โ filter candidates
โ ML scoring model โ pre-computed deck (Redis)
โ Deck refresher (background job, hourly per user)
Media: Photos โ S3 + CDN (face-detected thumbnail generation)Security Considerations
| Threat | Mitigation |
|---|---|
| Profile spoofing / catfishing | Photo verification (selfie match); phone number verification |
| Harassment / block | Block/report flow; moderation queue; ML classifier |
| Location precision leakage | Show distance (e.g., "3 km") not precise location; fuzzing |
| Profile scraping | Rate limit swipe API; anomaly detection on systematic viewing |
| CSAM | Age verification at signup; photo hash scanning |
Interview Tips
don't generate the deck on every request. Show the deck cache + background refresher pattern.
is the most interesting algorithmic problem โ the Redis bloom filter for fast reverse-like lookup shows real engineering instinct.
same as Uber/Yelp (geohash).