All system design challenges
#23 Counter Contention/Sharding

High-Profile Like Counter

Count likes on a post that receives tens of thousands a second, when every one of them wants to update the same number.

Asked at Meta Twitter

What is being asked

A celebrity's post goes viral. Design a like counter that absorbs the write storm on a single item, shows a count that is near real time, and still knows exactly who liked what.

Requirements

Functional

  • Like and unlike; a user can like a post once.
  • Show the count; show whether the viewer has liked it.

Non-functional

  • A single post may take tens of thousands of writes per second.
  • The displayed count may lag by seconds.
  • The stored record of who liked what must be exact.

Design

ClientLike APILike events logLikes table: user +postCounter aggregatorCount cacheCounts table, shardedcountersRead path
Boxes are services; rounded shapes are data stores and queues.
  1. A like is inserted into a table keyed by (post, user), which enforces one like per user and answers "have I liked this".
  2. The API also emits an event. It does not update a count row in the same request.
  3. An aggregator consumes events in small batches and applies the net change, such as +3,812, to the counter in one update.
  4. The count is cached and read from the cache. The viewer's own like is applied on their screen immediately.

Key decisions and trade-offs

  • The hot row problem. Thousands of transactions updating one row queue behind its lock. Batching turns thousands of writes into one.
  • Sharded counters. Alternatively keep N counter rows per post and add to a random one; the total is their sum. It spreads lock contention at the cost of a slightly more expensive read.
  • Approximate display, exact record. Nobody can tell 1,203,441 from 1,203,460, so the visible number may be eventually consistent while the likes table stays exact and the count can be rebuilt from it.
  • Idempotency. Events can be delivered twice; the aggregator must de-duplicate, or derive counts from the likes table periodically.

Follow-up questions

  • How do you show an exact count for a post with only twelve likes?
  • How would you repair a counter that has drifted?
  • How do you store the likes table for a post with 50 million likes?
  • How would you detect and remove likes from fake accounts afterwards?
Log in to tick off the challenges you have worked through. Log in