Understanding Redis Sorted Set Implementation and Real‑World Leaderboard Use Cases
This article explains the Redis Sorted Set data type, its underlying storage mechanisms (listpack and skiplist + dict), the internal structures and algorithms, and demonstrates how to build a real‑time game leaderboard using ZADD, ZRANGE and ZREVRANK commands.
Introduction
In this tutorial the author, nicknamed "Code Brother", gives a concise overview of the Redis Sorted Set data type, its low‑level implementation, and a practical game‑leaderboard example, using only seven diagrams.
1. What is a Sorted Set?
Sorted Sets are similar to regular Sets but each element consists of a member and a score . The score is a double value; elements are ordered by score from low to high, and when scores are equal the lexical order of the member is used.
Typical use cases include:
Leaderboards (e.g., top‑10 player rankings in online games)
Rate limiters built on sliding windows
Delayed queues where the score stores an expiration timestamp
2. Implementation Details
Redis stores Sorted Sets in two possible ways:
Before Redis 7.0 the data was stored in a ziplist , replaced by listpack in later versions. Listpack is used when the number of elements is ≤ zset-max-listpack-entries (default 128) and each member’s size is < zset-max-listpack-value (default 64).
If the above conditions are not met, Redis uses a combination of a skiplist and a dict (hash table). The dict stores member → score for O(1) single‑element lookups, while the skiplist enables O(log n) range queries.
MySQL: "listpack is suitable for scenarios with few elements and small element size."
The relevant source files are server.h (structure definitions) and t_zset.c (command implementations).
Skiplist + Dict
A skiplist is an ordered linked list with multiple forward pointers (levels) that provides binary‑search‑like performance. Each node contains:
typedef struct zskiplistNode {
sds ele; // member string
double score; // member score
struct zskiplistNode *backward; // backward pointer (level 0 only)
struct zskiplistLevel {
struct zskiplistNode *forward; // forward pointer for this level
unsigned long span; // number of level‑0 nodes skipped
} level[]; // flexible array of levels
} zskiplistNode;The skiplist header stores pointers to the first and last nodes, the total length, and the current maximum level.
Listpack
When the listpack conditions are satisfied, Redis stores each (member, score) pair compactly in a contiguous memory block. The decision logic resides in zaddGenericCommand inside t_zset.c :
void zaddGenericCommand(client *c, int flags) {
// ...
if (server.zset_max_listpack_entries == 0 ||
server.zset_max_listpack_value < sdslen(c->argv[scoreidx+1]->ptr)) {
zobj = createZsetObject(); // use skiplist+dict
} else {
zobj = createZsetListpackObject(); // use listpack
}
// ...
}3. Practical Leaderboard
Requirements:
Retrieve the top N players ordered by score (higher score = higher rank).
Add new players.
Query a specific player's rank and score.
Score composition combines the raw game score with a fractional part derived from the time the score was achieved, ensuring that when scores are equal the earlier player ranks higher:
private double calcScore(int playerScore, long playerScoreTime) {
return playerScore + (BASE_TIME - playerScoreTime) * 1.0 / BASE_TIME;
}Example commands (assuming BASE_TIME is a far‑future timestamp):
redis> ZADD leaderboard:339 2500.994707057989 player:1
redis> ZADD leaderboard:339 500.99470705798905 player:2
redis> ZADD leaderboard:339 500.9947097814618 player:3
redis> ZADD leaderboard:339 987770.994707058 player:4Updating a player's score:
ZADD leaderboard:339 1987770.994707055 player:4Getting the top 3 players (score descending with member and score returned):
ZRANGE leaderboard:339 0 2 REV WITHSCORESResult:
player:4
1987770.9947070549
player:1
2500.9947070579892
player:3
500.99470978146178Fetching a specific player's rank (0‑based):
ZREVRANK leaderboard:339 player:4Result: 0 (first place).
4. Further Reading
The author links to dozens of additional Redis articles covering Hash, Set, List, String, and source‑code debugging topics.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.