DDSA Solutions
Case Study6 min read·

Design a Distributed Counter

How to design distributed counters for interviews: Redis INCR, sharded counters, CRDTs, approximate counts, write buffering, and read-your-writes trade-offs.

Like counts, view counts, inventory soft caps, and rate limiter buckets all need counters under contention. A single DB row becomes a hotspot instantly. The interview is about spreading writes and stating how stale or approximate a read may be.

Scope with the framework: incr/decr by delta, get current value, optional reset, accuracy vs QPS. Tie to Redis and CAP.

Functional requirements

  • Increment(key, delta) and Decrement(key, delta).
  • Get(key) → current count (exact or approximate - say which).
  • Optional: GetAtLeast / GetApprox for cheaper paths.
  • TTL or daily buckets for time-windowed counts.

Non-functional requirements

  • Very high write QPS on hot keys (viral posts).
  • Low latency reads for rendering counts on pages.
  • Durability: losing a few increments on crash may be OK for likes - not for money.
  • Horizontal scale without a single-row bottleneck.

Exact and hot do not mix cheaply

If every increment must be globally serialised and durable, throughput dies. Most social counts accept eventual consistency or ±1% error. Billing and stock need different tools (ledger / inventory service).

Approach ladder

ApproachProsCons
Single Redis INCRSimple, atomic, fastOne key hotspot; memory lost on crash unless AOF
DB row + retriesDurableLocks / hot page
Sharded countersSpreads writesReads must sum shards
Write buffer + flushSmooths spikesDelayed visibility
CRDT G-Counter / PN-CounterMulti-region mergeMore complex; grow with replicas

Sharded counter design

  1. Pick N shards: key#0 .. key#(N-1).
  2. Increment: choose shard by hash(request_id) or random → INCR that shard.
  3. Get: MGET all shards and sum (or cache the sum for a second).
  4. Grow N when write QPS climbs; mention re-sharding pain.

N ≈ 10-100 is a common interview starting point. Reads become O(N). Mitigate with a periodically refreshed total in another key, knowing it lags. For leaderboards you often want sorted sets instead of raw counters.

Async aggregation

Apps enqueue +1 events to Kafka; consumers batch-update shards or a warehouse. UI reads a slightly stale cache. This matches ad click style pipelines when volume explodes.

Multi-region

Active-active: each region owns local shards; a CRDT merge (max per replica id for G-Counters) yields a global value. Or designate a primary region for exact counts and accept cross-region latency. Be explicit which model you pick.

Worked example

  1. Viral video like counter; target 200k writes/s.
  2. Use 64 Redis shards video123#i; clients INCR a random shard.
  3. Read path sums shards every request for admin; public page reads a 1s cached total.
  4. Nightly job persists totals to durable DB for analytics.

Interview summary

Start with INCR, then shard for hot keys, then async or CRDT for multi-region. State accuracy SLOs. That progression is the distributed counter interview.

More in this series