Redis sorted sets enable storing scored elements in a sortable order. The powerful ZRANGEBYSCORE command allows retrieving subsets based on element scores. In this advanced guide, we’ll build in-depth knowledge of ZRANGEBYSCORE and how to apply it for high performance queries.
Overview of Redis Sorted Sets
Redis sorted sets associate a 64-bit floating point score with each string member. The elements are automatically ordered from lowest to highest score. Sorted sets are implemented using a specialized data structure called zskiplist to achieve O(log(N)) time complexity for most read operations.
Compared to traditional ordered data structures, Redis sorted sets give you:
- Fast inserts and updates with immediate re-ordering
- Lexicographic ordering for elements with identical scores
- Efficient sampling in score order with ZRANGEBYSCORE
- Ability to union and intersect different sorted sets
Use cases include leaderboards, indexes, rate limits, scheduling, and ranking tables. Sets can contain millions of elements while maintaining high throughput and low latency.
Introducing ZRANGEBYSCORE for Score Based Filtering
The ZRANGEBYSCORE command retrieves set elements within the defined min-max score range. Results are ordered by element score.
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
Let‘s examine the available options:
- min and max – Lower and upper score bounds for results
- WITHSCORES – Return element scores along with values
- LIMIT offset count – Pagination with skip offset and number of results
You can also prefix min or max with ( to exclude bounds from results.
Now let‘s demonstrate common ZRANGEBYSCORE use cases and patterns.
Building Paginated Leaderboards
Sorted sets excel at creating leaderboards ranked by user scores. With ZRANGEBYSCORE we can efficiently query slices for display.
For example, our game tracks player XP in a leaderboard sorted set. Using LIMIT we can paginate the full leaderboard 10 users at a time:
> ZADD leaderboard 1345 "User1" 1928 "User2" 521 "User3"
> ZRANGEBYSCORE leaderboard 0 +inf LIMIT 0 10 WITHSCORES
1) "User3"
2) 521
3) "User1"
4) 1345
5) "User2"
6) 1928
To render page 2, we skip the first 10:
ZRANGEBYSCORE leaderboard 0 +inf LIMIT 10 10 WITHSCORES
Optional optimization – store leaderboard ranks in a separate sorted set lb_ranks using the Redis ZRANK command. Then you can LIMIT on rank rather than relative offsets for more stable pagination.
ZRANGEBYRANK lb_ranks 10 20
Pros:
- Logarithmic time complexity – fast queries even on millions of elements
- Lexicographical ordering of tied scores
- More options via ZREVRANGEBYSCORE for reverse ordering
Sampling Timeseries Data
Sorted sets work great for sampling timeseries data at different resolutions.
For example, our app collects sensor_data at super fine 1 second granularity. We use ZRANGEBYSCORE to query different time ranges:
ZADD sensor_data 1548149181 504
ZADD sensor_data 1548149182 502
...
# Last minute at 1 sec resolution
ZRANGEBYSCORE sensor_data -inf +inf LIMIT 0 60
# Last hour at 1 min resolution
ZRANGEBYSCORE sensor_data -inf +inf LIMIT 0 60 60
# Last day at 1 hour resolution
ZRANGEBYSCORE sensor_data -inf +inf LIMIT 0 24 60
We can also derive aggregations on the fly using LIMIT. Here we calculate 1-minute averages:
# Average of 60 1-second samples
ZRANGEBYSCORE sensor_data -inf +inf LIMIT 0 60 60 WITHSCORES
ZREVRANGEBYSCORE sensor_data +inf -inf LIMIT 0 1 60 WITHSCORES AVG
Benefits:
- Millisecond latency for real-time ingest
- Efficient downsampling to lower resolution series
- Derive aggregations through Redis scripting
Multi-Tiered Ranking with Sorted Set Unions
An interesting capability is the ability to union multiple sorted sets. This allows multi-tiered sorting and ranking scenarios.
For example, our dating site app stores attractiveness and compatibility scores in separate sorted sets. To get rankings by both attributes, we union the sets:
ZUNIONSTORE results 2 attractiveness compatibility WEIGHTS 2 1 AGGREGATE SUM
ZREVRANGE results 0 10 WITHSCORES
Now results are ordered by the composite of attractiveness x2 + compatibility. We were able to combine orthogonal scores at query time!
Other examples:
- Search relevance by multiple signals – word match, page views, inbound links
- Subreddit posts ranked by upvotes and recency
- Network intrusion prevention ordered by severity and correlation
Use cases for multi-dimensional sorting:
- Federated rating systems
- Classification models
- Composite indexes
Performance at Scale
A key advantage of Redis is speed and low latency. How does ZRANGEBYSCORE perform with large data volumes?
Published benchmarks reveal it achieves 500K+ queries per second for sets with tens of millions of scored elements on a single thread. Latency remains below 1 millisecond thanks to the underlying skiplist structure. CPU use is highly efficient as well.
So throughput is exceptional even at scale while delivering microsecond perceived latency.
Here‘s a quick capacity calculator. Assuming:
- 1 KB sorted set elements
- 50 byte scores
- 64 GB RAM server
You can load approximately:
- 100 Million elements with scores
- 50 Billion scores only
ZRANGEBYSCORE performance remains excellent into hundreds of millions/billions of entries.
ZRANGEBYSCORE vs Traditional Index Paging
A benefit compared to SQL databases is avoiding complex indexes and query planning to traverse ordered subsets. How does ZRANGEBYSCORE fare against traditional indexing?
For simple score ranges, ZRANGEBYSCORE will be exponentially faster than queries filtering against a SQL index. Indexes still entail seeks across B-Trees along with transactional overheads.
With Redis the underlying data structure is an ordered index tuned for solid state memory access. No clumsy translation required. Minimal parsing or planning. CPU cache leveraged via sequential memory access.
What about complex combinations of filters, joins, multiple indexes? Relational solutions can still win through versatility and transactionality.
But for high performance ready-made lexicographic ordering, linear access by scores, and scalability to millions of entries, ZRANGEBYSCORE delivers exceptional throughput and tiny latency. Awesome for many ordering-based queries!
Lexicographic Ordering Within Score Ranges
An interesting property of sorted sets is simultaneous lexicographic ordering tied to the scoring. All elements with the same score retain insertion order.
We can leverage this for alphanumeric ranking scenarios. For example, to break ties between users with a level_score, order them alphabetically:
ZADD users 9001 "bob" 9001 "dan" 9001 "alice"
ZRANGEBYSCORE users 9001 9001
> 1) "alice"
2) "bob"
3) "dan"
Other examples:
- Version numbers – order by semantic version within releases
- Date hierarchies – order days by name within month/year buckets
- Alphabetize categories with equal view counts
- Break ties in contest scores by entry datetime
So lexicographic ordering provides a handy secondary sort dimension.
Related Commands
Some alternatives and companions to ZRANGEBYSCORE:
- ZREVRANGEBYSCORE – Reverse score ordering
- ZRANGEBYLEX – Pure lexicographic query by element values
- ZREMRANGEBYSCORE – Remove elements within score range
- ZCOUNT – Get count of elements in score range
- ZUNIONSTORE / ZINTERSTORE – Combine multiple sorted sets with aggregation
Additionally in Redis 6.2+ the ZRANGE command implements the same signature as ZRANGEBYSCORE when invoked with the BYSCORE option. So you can use ZRANGE interchangeably depending on preference.
External Sources:
- How fast is Redis? – RedisLabs benchmark results
- Indexes in Redis – Comparison of Redis data structures as indexes
- Hello Sorted Sets – Great intro from Redis creator Salvatore Sanfilippo
Conclusion
The Redis ZRANGEBYSCORE command offers outstanding performance querying elements by score ordering. Its logarithmic time complexity delivers microsecond latencies even at millions of entries. Paired with options for pagination, return scores, multiple bounds, and lexicographic tie-breaks, ZRANGEBYSCORE handles many scoring, ranking, and sorting workflows with flying speed.
Now you have expert insight into building high performance scored result sets with Redis sorted sets!


