system design · system-design

Design a Distributed Counter (Sharded + Eventually Consistent)

Sharded counters, eventual consistency, write-heavy. View counts, like counters, page views.

medium3hgeneralredissystem-design
Ask GPTConfidence

Theory

Explanation

Intuition first, formal definition second. Skim the bullets if you already know this; read the prose if you don't.

Counter on one row = hotspot for popular content (1M writes/sec on a single key). Shard counter across N keys; sum at read. Reads are slightly more expensive (N reads); writes scale linearly.

Write picks random shard from {key:0, key:1, ..., key:N-1}, INCR. Read SUM all shards. Periodic rollup compacts shards into snapshot row. CRDT (G-counter) is the formal abstraction. Approximate counts via HyperLogLog for very-large unique cardinality.

When to use

Likes, views, votes, click counters at scale.

When not to

Tiny counters (single key fine). Strict-monotonic global counters (use Spanner).

flowchart LR
  Client([Client]) --> LB[Load Balancer]
  LB -->|random shard| S0[(Shard 0)]
  LB -->|random shard| S1[(Shard 1)]
  LB -->|random shard| SN[(Shard N)]
  Reader[Read API] --> S0
  Reader --> S1
  Reader --> SN
  Reader --> Sum[SUM]
  Rollup[Daily Rollup] -.compact.-> Snapshot[(Snapshot)]

Key insights

  • Shard count determines write capacity ceiling. 10 shards = 10x single-key write rate.
  • Read amplification = N. Pick N to balance read vs write cost.
  • CRDT semantics: add-only counters monotonically grow; convergent on merge.
  • For unique-count (e.g., unique viewers), use HyperLogLog (HLL), fixed memory, approximate.
  • Rollup reduces read amplification long-term: snapshot + shards delta since snapshot.