Problem statement
Design the counting service behind a large content platform (think a popular short-video feed) that tracks how many times each item was viewed and how many likes it holds, then shows those totals back to viewers. Every playback and every tap of the heart is an increment; every render of a card wants the current numbers. The interesting part is that writes vastly outnumber reads on the hot path, and the traffic is brutally skewed toward a handful of trending items.
Operating context. The catalog holds ~2 billion items. Aggregate increments run at ~500,000/sec on a normal day and burst past 2,000,000/sec when something goes viral, while read requests for the displayed totals run ~150,000/sec. On any given hour, the top ~1,000 items absorb a large share of all increments — a single trending clip can take 50,000 increments/sec by itself. A view is a fire-and-forget signal that may be reasonably approximate; a like is a per-user toggle where a given user's like must count at most once and the user must see their own toggle reflect immediately. Displayed totals may lag reality by a few seconds for non-actors.
Out of scope. The recommendation/feed ranking, video storage and transcoding, spam/bot detection beyond a mention of where it hooks in, the client UI, and cross-item analytics dashboards (assume a separate warehouse pipeline consumes the same event stream).
What to produce. A high-level architecture covering: the increment (write) path and the read path with their API shapes; how you shard or aggregate a per-item counter so no single row becomes a bottleneck; where you sit on the approximate-vs-exact spectrum for views versus likes and why; how you special-case hot items; how a like stays idempotent per (user, item) so a double-tap or a client retry doesn't inflate the count; and how reads are cached and refreshed so the display path stays cheap. Sketch the major components and the flow between them; checkpoints will probe the hot-item write path and the like-idempotency scheme specifically.
Functional requirements
- Record a view increment for an item as a fire-and-forget signal on the hot path.
- Toggle a like for an (item, user) pair so each user contributes at most one like per item.
- Return the current view total and like total for a batch of items on a card render.
- Reflect a user's own like/unlike immediately in what they see, even before global totals converge.
- Expose the raw increment stream to a downstream warehouse without slowing the counting path.
- Serve a friendly zeroed/last-known value when an item's counters are cold or unavailable.
Non-functional requirements
- Sustain 500000 increments/sec steady with bursts to 2000000/sec; absorb spikes without dropping the hot path.
- Read path (batched totals) p99 < 80 ms; increment enqueue p99 < 20 ms.
- A single trending item taking 50000 increments/sec must not create a hot-row bottleneck.
- Likes are exactly-once per (user, item): a double-tap or client retry never inflates the total.
- Displayed totals may lag true totals by up to ~5 s for non-actors; the actor's own toggle is immediate.
- 99.95% availability for reads; view increments may be lossy under overload but likes must not be lost.
Topics
- System Design HLD
- Scaling Write-Heavy
- Data Cache
- Reliability Idempotency
- Consistency Eventual