Swipe Storage at Scale
Tinder processes 1.6 billion swipes per day. Each swipe is a binary decision: left (pass) or right (like). This data drives match detection, recommendation quality, and abuse prevention. Swipe storage is a write-heavy, eventually consistent problem with specific read patterns: “has user A already swiped on user B?” and “who has liked user A?”
Write Path#
At 1.6 billion swipes per day, that’s 18,500 writes per second on average, with heavy peaks during evenings. Each swipe record: (swiper_id, swiped_id, direction, timestamp). This is append-only: swipes are immutable once made (no editing a swipe).
A single relational database won’t sustain this write volume. Shard by swiper_id. User A’s swipe history lives on one shard. Write routing: hash swiper_id to a shard. No cross-shard coordination needed for writes.
The “Already Swiped” Check#
Before showing user B to user A, check if A has already swiped on B. This prevents re-showing profiles. The query: SELECT 1 FROM swipes WHERE swiper_id=A AND swiped_id=B.
With billions of swipe rows, even with an index on (swiper_id, swiped_id), this read is fast. But at 18,500 swipes/second, you’re doing this check just as frequently.
Cache it in Redis: SET swipe:A:B direction EX 604800 (7-day TTL). Check Redis first; fall back to database only on cache miss. The cache hit rate for active users is above 95%.
Consistency Trade-offs#
Swipe storage can tolerate eventual consistency. If a swipe write is replicated asynchronously to read replicas, there’s a small window where the “already swiped” check on a replica misses a recent swipe. The consequence: user A briefly sees a profile they already swiped on. Not a correctness disaster — they just swipe again.
Strong consistency here would require all reads to go to the primary, increasing load. For swipe data, eventual consistency with a short replication lag (under 1 second) is the right trade-off.
Left Swipe Retention#
Left swipes (passes) don’t need to be stored forever. After 30 days, a passed profile can be re-shown. This bounds the storage growth: swipe records older than 30 days are eligible for deletion. An archived cold storage keeps historical swipe data for analytics (recommendation model training) without it living in the hot swipe database.
At Salesforce#
Salesforce had a similar pattern for “dismissed” notifications: users could dismiss a notification and it shouldn’t reappear. Dismiss events were write-heavy and only needed to be checked against the specific (user_id, notification_id) pair. We used Redis with a 30-day TTL for dismissed pairs. After 30 days, a notification could theoretically resurface — acceptable because notifications older than 30 days were already expired and wouldn’t be generated.
What I’m Learning#
Swipe storage illustrates that not all data needs the same retention or consistency level. Right swipes matter for match detection and need reliable storage. Left swipes are advisory and can tolerate TTL-based expiry. Separating these access patterns leads to simpler and cheaper storage architecture.
Have you designed systems where different subsets of the same data needed different consistency or retention policies?