Design a like/unlike system with concrete user-item keys, count storage, and Redis cache records. Explain idempotent desired-state writes, batched reads, repeated events, cache races, and the tradeoff between exact counts and hot-item scalability.
Design a Like and Unlike Counter with Explicit Storage and Cache Keys
Company: Roblox
Role: Software Engineer
Category: System Design
Difficulty: medium
Interview Round: Onsite
Design a like/unlike counter system. Give concrete database schemas, Redis key designs, and query patterns rather than stopping at a component diagram.
Explain how a user changes their like state, how the system returns an item's count and the user's own state, and what happens under retries and concurrent requests.
### Constraints & Assumptions
- Clarify the object being liked, read/write volume, and required count freshness.
- A repeated "like" request should not accidentally behave as "unlike" unless a toggle API is explicitly intended.
- Distinguish authoritative user/item state from cached aggregate counts.
### Clarifying Questions to Ask
- Must the count be exact immediately, or may it lag behind the user's own state?
- Can clients set an explicit desired state rather than sending an ambiguous toggle?
- Are there extremely popular items that create write contention?
### Part 1 — Store and Change Like State
Specify keys, constraints, and the transaction or event flow for like and unlike operations.
#### What This Part Should Cover
- Unique user/item identity and idempotent desired-state operations.
- Count changes only when the state actually changes.
- Concurrent requests and durable event publication if used.
### Part 2 — Serve Counts and User State
Provide cache keys and representative read paths, including invalidation or projection updates.
#### What This Part Should Cover
- Batched reads for multiple items.
- Cache misses, stale values, and repeated events.
- A strategy for hot items and a clear consistency tradeoff.
```hint
Incrementing Redis for every received "like" request counts retries as new likes unless the state transition is deduplicated first.
```
### What a Strong Answer Covers
The design should make the source of truth and consistency boundary explicit. Schema constraints, cache keys, and update rules must agree on what one like means and remain correct when messages or requests repeat.
### Follow-up Questions
- How would you rebuild a lost count cache?
- What if a user likes and then unlikes before a cache update is processed?
- Which bottleneck appears if every write updates one popular item's count row?
Overview: Design a like/unlike system with concrete user-item keys, count storage, and Redis cache records. Explain idempotent desired-state writes, batched reads, repeated events, cache races, and the tradeoff between exact counts and hot-item scalability.
Design a Like and Unlike Counter with Explicit Storage and Cache Keys
Roblox
Oct 16, 2026
mediumSoftware EngineerOnsiteSystem Design
0
0
Design a like/unlike counter system. Give concrete database schemas, Redis key designs, and query patterns rather than stopping at a component diagram.
Explain how a user changes their like state, how the system returns an item's count and the user's own state, and what happens under retries and concurrent requests.
Constraints & Assumptions
Clarify the object being liked, read/write volume, and required count freshness.
A repeated "like" request should not accidentally behave as "unlike" unless a toggle API is explicitly intended.
Distinguish authoritative user/item state from cached aggregate counts.
Clarifying Questions to Ask Guidance
Must the count be exact immediately, or may it lag behind the user's own state?
Can clients set an explicit desired state rather than sending an ambiguous toggle?
Are there extremely popular items that create write contention?
Part 1 — Store and Change Like State
Specify keys, constraints, and the transaction or event flow for like and unlike operations.
What This Part Should Cover Guidance
Unique user/item identity and idempotent desired-state operations.
Count changes only when the state actually changes.
Concurrent requests and durable event publication if used.
Part 2 — Serve Counts and User State
Provide cache keys and representative read paths, including invalidation or projection updates.
What This Part Should Cover Guidance
Batched reads for multiple items.
Cache misses, stale values, and repeated events.
A strategy for hot items and a clear consistency tradeoff.
What a Strong Answer Covers Guidance
The design should make the source of truth and consistency boundary explicit. Schema constraints, cache keys, and update rules must agree on what one like means and remain correct when messages or requests repeat.
Follow-up Questions Guidance
How would you rebuild a lost count cache?
What if a user likes and then unlikes before a cache update is processed?
Which bottleneck appears if every write updates one popular item's count row?