100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

How Would You Design a Real-Time Leaderboard?

Learn how to design a real-time leaderboard using sorted sets for fast rank and top-N queries, sharding, and snapshots at scale.

mediumQ49 of 224 in System Design Est. time: 5 minsLast updated:
Open Code Lab

Expected Interview Answer

A real-time leaderboard ranks a large, constantly updating set of scores and answers “what is this player’s rank” and “who are the top N” in near-constant time, which is best solved with a sorted-set data structure (like Redis ZSET) that keeps members ordered by score with O(log N) inserts and rank lookups instead of re-sorting on every query.

Every score update becomes an atomic ZADD/ZINCRBY-style operation on the sorted set, which internally maintains a skip list so the structure stays ordered without a full re-sort. Reading the top N is an O(log N + N) range query, and finding a specific player’s rank is O(log N), both fast enough to serve directly from cache at read time. At very large scale, a single sorted set becomes a hot key, so the leaderboard is sharded (e.g., by region or game mode) with periodic merges for a global view, and historical/seasonal leaderboards are computed as materialized snapshots rather than live-queried to avoid recomputation cost. Write-heavy competitive scenarios add debouncing or batching of score updates client-side to avoid overwhelming the sorted set with redundant writes for the same player within milliseconds.

  • Sorted-set structures give O(log N) rank and top-N queries instead of full re-sorts
  • Atomic score updates keep the leaderboard consistent under high concurrent write volume
  • Sharding by region/mode avoids a single sorted set becoming a write hotspot at massive scale
  • Snapshotting historical/seasonal boards avoids expensive recomputation for past periods

AI Mentor Explanation

A real-time leaderboard is like the live tournament points table that stays instantly ordered after every match instead of being manually re-tallied and re-sorted from scratch. Each result updates one team’s points and the table quietly re-slots that team into its correct position using an internal ordering structure, so nobody re-ranks all sixteen teams from zero after every game. Fans checking “who is in the top four” get an instant answer because the table is always pre-sorted, not computed on demand. That always-ordered, incrementally updated structure is exactly what a sorted-set-backed leaderboard provides.

Step-by-Step Explanation

  1. Step 1

    Model scores as a sorted set

    Store player-to-score mappings in a sorted-set structure (e.g., Redis ZSET) keyed by leaderboard ID, ordered by score.

  2. Step 2

    Update atomically on each event

    Score changes use an atomic increment/update against the sorted set, which internally re-slots the member in O(log N).

  3. Step 3

    Serve rank and top-N reads from cache

    Answer “top N” and “my rank” queries directly from the sorted set in O(log N + N) without any full sort.

  4. Step 4

    Shard and snapshot at scale

    Partition by region/mode to avoid a single hot sorted set, and materialize periodic snapshots for historical/seasonal views.

What Interviewer Expects

  • Names a concrete sorted-set structure (Redis ZSET or an equivalent skip-list-backed store)
  • Explains why O(log N) incremental updates beat re-sorting the whole leaderboard on every change
  • Addresses scale: sharding a hot leaderboard and how to compute a merged/global view
  • Discusses historical/seasonal leaderboards as snapshots rather than always-live queries

Common Mistakes

  • Proposing a full SQL ORDER BY re-sort on every score update at scale
  • Not considering that a single global leaderboard key becomes a write hotspot under massive concurrency
  • Forgetting how “my current rank” is queried efficiently, not just the top N
  • Ignoring how historical/seasonal leaderboards are preserved once a season resets

Best Answer (HR Friendly)

I would keep player scores in a data structure that stays automatically sorted as scores change, like a sorted set in Redis, so both “show me the top ten” and “what is my current rank” are fast lookups rather than expensive re-sorts. For very large scale, I would split the leaderboard by region or game mode to avoid one single hot spot, and store past seasons as fixed snapshots instead of recalculating them live.

Code Example

Leaderboard update and query using a Redis-style sorted set
async function recordScore(leaderboardId, playerId, score) {
  // Atomically upsert; the sorted set stays ordered internally (skip list)
  await redis.zadd(`lb:${leaderboardId}`, score, playerId)
}

async function getTopN(leaderboardId, n = 10) {
  // O(log N + n) range query, no full sort needed
  const raw = await redis.zrevrange(`lb:${leaderboardId}`, 0, n - 1, "WITHSCORES")
  return parsePlayersWithScores(raw)
}

async function getPlayerRank(leaderboardId, playerId) {
  // O(log N) rank lookup
  const rank = await redis.zrevrank(`lb:${leaderboardId}`, playerId)
  const score = await redis.zscore(`lb:${leaderboardId}`, playerId)
  return rank === null ? null : { rank: rank + 1, score }
}

Follow-up Questions

  • How would you shard a leaderboard with tens of millions of players across regions?
  • How would you handle ties in score when ranking players deterministically?
  • How would you snapshot a seasonal leaderboard so past results remain queryable after a reset?
  • How would you throttle extremely bursty score updates from a single player without losing correctness?

MCQ Practice

1. Why is a sorted-set structure preferred over re-sorting a list on every score change?

A sorted set (backed by a skip list) maintains order incrementally, so both updates and rank queries stay logarithmic instead of requiring a full re-sort.

2. What is the main reason a single global leaderboard key can become a problem at massive scale?

When every player worldwide writes to one sorted set, that single key becomes a concurrency bottleneck, motivating sharding by region or mode.

3. Why are historical/seasonal leaderboards typically stored as snapshots rather than computed live?

Once a season ends, its final ranking is fixed, so persisting a snapshot avoids wasted recomputation on every historical query.

Flash Cards

What data structure best fits a real-time leaderboard?A sorted set (e.g. Redis ZSET), which maintains order via a skip list for O(log N) updates and lookups.

Why avoid re-sorting on every score change?Because a sorted set updates incrementally in O(log N) instead of re-sorting the whole dataset.

How do you scale past one hot leaderboard key?Shard by region/mode and merge periodically for a global view.

How are past seasons usually handled?As materialized snapshots taken at season end, not recomputed live.

1 / 4

Continue Learning