Skip to content
Muhammet Şafak
tr
Asked by: Sarp Answered:

Why should I use a Sorted Set for a live leaderboard in Redis?


Question

I'm designing a live leaderboard (the top 100 highest-scoring players) for a gaming platform; millions of players' scores change in real time. I want to keep the data in Redis. Instead of storing each player's score in a plain String key (`user:123:score`) and pulling all users to sort them every time, what are the architectural advantages and the time-complexity (O(log N)) analysis of using Redis's Sorted Set (ZSET) data type?

Answer

Short answer: storing scores as plain user:123:score strings and sorting in the app is O(N log N) per read over millions of keys — and you re-fetch everything each time. The right tool is a Sorted Set (ZSET).

The real point: the nature of a leaderboard is “sort and give me the top N.” If you try to do that work at read time, scale crushes you; you need to move the sorting to write time.

  1. O(log N) updates with ZADD. ZADD leaderboard <score> <user> updates a member’s score in O(log N). When a player’s score changes it’s a single command; you don’t touch the whole table. The moment the score changes the set stays internally sorted.
  2. Already-sorted top 100 with ZREVRANGE. ZREVRANGE leaderboard 0 99 WITHSCORES returns the top 100 players already sorted in O(log N + 100). You do no sorting on the app side; even with millions of players this read is near-constant cost.
  3. One player’s rank with ZREVRANK. “What rank am I?” is answered by ZREVRANK leaderboard <user> in O(log N). With the string approach you’d have to fetch and count everyone; with a ZSET it’s a single command.
  4. The skip-list sorts as you write. The skip-list behind a ZSET keeps everything ordered as you write. So the cost is spread to write time, not read time; reads stay cheap and almost independent of player count.
  5. Window large sets. For huge sets, use periodic snapshots and time-windowed boards (separate daily/weekly keys). Watch ties: equal scores order lexicographically; if needed, encode a tiebreaker (e.g. a timestamp) into the score to make the order deterministic.

Bottom line: a ZSET is purpose-built for live leaderboards; use it instead of strings + app-side sorting. The moment you move sorting out of read time and into write time, the leaderboard runs instant and cheap even with millions of players.

Tags: #data#redis#performance
Share:

Comments

Sign in with your GitHub account to join the discussion. Comments are stored in GitHub Discussions.

More Questions

All questions

Search the site

Start typing to search posts, projects and pages.

Esc to close Powered by Pagefind