Sponsor
Your Product
List your product
Interactive system design

How would you store millions of likes?

Model a social like as a durable relationship, then scale the write path with partitioning, asynchronous work, and cached counters.

Explore the architecture

The core record

(post_id, user_id)

one unique like edge

A durable edge is the source of truth. Counts and feeds are derived views that can be rebuilt or updated asynchronously.

Important: This is an illustrative scalable design for learning system-design trade-offs. It is not a description of Instagram's confirmed internal architecture.

Architecture flow

Write once, build useful views

Separate the durable like edge from read-optimized counters. The stream connects them and lets each consumer scale independently.

Like API

Authenticate the actor and validate the post and requested action.

Idempotent write

Represent a like as a unique (postId, userId) edge. Retries should not create duplicate likes.

Durable event stream

Persist the change before acknowledging it; consumers can retry work from this log.

Sharded edge store

Partition each post into user-hash buckets to spread hot-post writes. Keep a user activity index for reverse lookups.

Async counters + cache

Aggregate increments in the background and serve a fast, eventually consistent count from a cache.

User activity index for reverse lookups
Event consumers retry independently
Read API combines edge and count views

Change the inputs

Rate and shard simulator

See how evenly distributing writes changes the average load per shard. This back-of-the-envelope model assumes even routing and a planning target of 5,000 writes per second per shard.

Real traffic is skewed: a viral post can be much hotter than the average. Bucketing a post's likes by user hash helps spread that hot key, but adds fan-out work for some reads.

Estimated even-share load

1,563writes / shard / sec

Planning target: 5,000 writes per shard per second (illustrative, not a vendor benchmark)

Suggested shards

10

at planning target

Likes per day

4,320,000,000

if rate is steady

Raw data per day

276.5 GB

at 64 bytes / edge

Storage estimate excludes indexes, replication, backups, compression, and stream retention. Capacity planning needs measured benchmarks and headroom.

Data model trade-offs

Store edges; derive counts

  • Source of truth: a uniquely constrained like edge supports duplicate-safe retries and unlike operations.
  • Hot posts: split post likes into buckets keyed by a stable hash of user ID; query fan-out becomes a deliberate read trade-off.
  • Fast counts: aggregate stream events into counter buckets and cache their sum; the displayed count may lag briefly.
  • Reverse access: maintain a user-oriented index or projection for “posts I liked” rather than scanning every post partition.

Diagram source

Mermaid flowchart

Copy this source into a Mermaid-compatible renderer to edit or share the architecture.

flowchart LR
  U[App / user] --> A[Like API]
  A --> V[Auth + validation]
  V --> D[Idempotent write]
  D --> E[Durable event stream]
  E --> W[Like workers]
  W --> S[(Sharded like-edge store)]
  E --> C[Counter aggregators]
  C --> K[(Counter cache)]
  S --> R[Read API]
  K --> R
  R --> U
  W --> I[(User activity index)]