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

Sorted Sets in Redis

Master Redis Sorted Sets, where every unique member carries a floating-point score, enabling leaderboards, priority queues, and range-based queries by rank or score.

Core Data StructuresIntermediate9 min readJul 10, 2026
Analogies

What Redis Sorted Sets Are

A Redis sorted set (ZSET) is like a regular set — every member is unique — except each member also carries a floating-point score, and the structure is kept continuously ordered by that score using an internal skip list plus a hash table for O(1) score lookups by member. This dual structure gives you O(log n) insertion, removal, and rank queries via ZADD, ZREM, and ZRANK, which is exactly the profile needed for real-time leaderboards, priority queues, and time-ordered indexes.

🏏

Cricket analogy: A sorted set is like the live IPL Orange Cap leaderboard — every batter is a unique member, their run total is the score, and the list stays continuously ranked so Virat Kohli's position updates instantly the moment he scores another boundary.

Adding Members and Querying by Rank or Score

ZADD sets or updates a member's score (and supports GT/LT flags to only update if the new score is greater or less than the current one, and INCR to add to the existing score atomically like a ZSET version of INCR), while ZSCORE reads a single member's score. ZRANGE (with the BYSCORE or REV options in modern Redis) and the legacy ZRANGEBYSCORE let you fetch members within a score range or by rank position, and ZRANK/ZREVRANK tell you a specific member's zero-based position from the lowest or highest score.

🏏

Cricket analogy: ZADD with GT is like only updating a bowler's 'best figures' score if their new spell beats the current record, the way Jasprit Bumrah's tracked best-figures entry only changes when he actually improves on it.

bash
# Leaderboard: add or update player scores
ZADD leaderboard 1500 "player:alice"
ZADD leaderboard 2200 "player:bob"
ZINCRBY leaderboard 50 "player:alice"     # atomically add to existing score

# Only update if strictly better (e.g. a personal-best tracker)
ZADD pb:100m GT 9.58 "runner:usain"

# Top 3 by score, highest first, with scores
ZREVRANGE leaderboard 0 2 WITHSCORES

# Everyone scoring between 1000 and 2000
ZRANGEBYSCORE leaderboard 1000 2000

# A specific player's rank (0-based, highest score = rank 0)
ZREVRANK leaderboard "player:bob"

# Expire old entries from a time-ordered index (score = unix timestamp)
ZREMRANGEBYSCORE events:log 0 1751500000

Leaderboards, Priority Queues, and Time-Ordered Indexes

The classic sorted-set use case is a leaderboard: ZADD to record or update a score, ZREVRANGE with WITHSCORES to display the top N players, and ZREVRANK to show any individual player their current rank — all served directly from Redis without a database sort. A second common pattern uses a Unix timestamp as the score to build a time-ordered index or a delayed-job priority queue, where ZRANGEBYSCORE with an upper bound of 'now' finds all jobs due to run, and ZADD with NX prevents accidentally rescheduling a job that's already queued.

🏏

Cricket analogy: Using a sorted set for the IPL Orange Cap race is like ZADD updating a batter's season run total after every innings and ZREVRANGE instantly serving the live top-10 to the broadcast graphics team.

ZADD GT and ZADD LT (added in Redis 6.2) let you implement 'record a new personal best' logic in a single atomic command — update the score only if the new value is strictly greater (or lesser) than the current one — without a client-side read-compare-write sequence.

Sorted set scores are IEEE 754 double-precision floats, so they lose exact integer precision above roughly 2^53. If you need exact ordering for very large integer IDs (like 19-digit snowflake IDs) as tie-breakers, encode them carefully — for example, combine a coarse timestamp score with the ID embedded in the member string itself rather than relying purely on score precision.

  • A sorted set combines unique membership (like a Set) with a floating-point score that keeps members continuously ranked.
  • ZADD, ZREM, and ZRANK/ZREVRANK run in O(log n) thanks to an internal skip list plus hash table.
  • ZADD's GT/LT flags and ZINCRBY enable atomic 'update only if better' and 'add to score' patterns.
  • ZRANGEBYSCORE and ZRANGE...BYSCORE fetch members within a score window, ideal for time-ordered or ranked queries.
  • Leaderboards are the flagship use case: ZREVRANGE WITHSCORES for top-N, ZREVRANK for an individual's rank.
  • Using a Unix timestamp as the score turns a sorted set into a delayed-job queue or time-ordered index.
  • Scores are double-precision floats, so extremely large integer IDs can lose precision if relied on for exact ordering.

Practice what you learned

Was this page helpful?

Topics covered

#Redis#RedisStudyNotes#Database#SortedSetsInRedis#Sorted#Sets#Adding#Members#StudyNotes#SkillVeris