ZADD-&-ZRANGE
Sorted Sets combine the uniqueness of Sets with a score for each member. Perfect for leaderboards, priority queues, and time-series data.
You'll Learn
- ZADD, ZRANGE, ZRANK syntax
- Score-based sorting and ranges
- Building leaderboards
- How Redimo shows rank and score visually
See Your Data, Not Terminal Text
Redimo visualizes every Redis data type beautifully. Edit inline, undo mistakes, stay safe in production.
1. What Is a Sorted Set?
A Sorted Set (ZSet) is like a Set, but each member has a numeric score. Members are automatically sorted by score, enabling efficient range queries and rankings. Like Sets, all members must be unique.
The magic of Sorted Sets is their efficiency: get the rank of any member in O(log N), get ranges by rank or score in O(log N + M), and update scores atomically. This makes them perfect for leaderboards, time-based data, and priority queues.
Syntax
ZADD key score member [score member ...] # Add with scores
ZRANGE key start stop [WITHSCORES] # Get range by rank (0-indexed)
ZREVRANGE key start stop [WITHSCORES] # Get range in reverse order
ZRANK key member # Get rank (0-indexed, ascending)
ZREVRANK key member # Get rank (descending)
ZSCORE key member # Get score
ZINCRBY key increment member # Increment score
ZREM key member [member ...] # Remove members
ZCOUNT key min max # Count members in score range
ZCARD key # Total member countSorted Set Advantages
- • Automatic sorting by score
- • O(log N) rank lookups
- • Range queries by rank or score
- • Atomic score updates
Best Use Cases
- • Game leaderboards
- • Priority/delayed job queues
- • Time-series data (score = timestamp)
- • Rate limiting sliding windows
2. The CLI Way (Hard Mode)
Building a game leaderboard in CLI means parsing scores from interleaved output and mentally calculating rankings:
Building a Leaderboard
127.0.0.1:6379> ZADD game:leaderboard 1500 "player:alice" 2300 "player:bob" 1800 "player:charlie" 3100 "player:diana"
(integer) 4
127.0.0.1:6379> ZRANGE game:leaderboard 0 -1 WITHSCORES
1) "player:alice"
2) "1500"
3) "player:charlie"
4) "1800"
5) "player:bob"
6) "2300"
7) "player:diana"
8) "3100"
127.0.0.1:6379> ZREVRANGE game:leaderboard 0 2 WITHSCORES
1) "player:diana"
2) "3100"
3) "player:bob"
4) "2300"
5) "player:charlie"
6) "1800"Querying Rankings
127.0.0.1:6379> ZRANK game:leaderboard "player:bob"
(integer) 2
127.0.0.1:6379> ZREVRANK game:leaderboard "player:bob"
(integer) 1
127.0.0.1:6379> ZSCORE game:leaderboard "player:bob"
"2300"
127.0.0.1:6379> ZINCRBY game:leaderboard 500 "player:alice"
"2000"
127.0.0.1:6379> ZCOUNT game:leaderboard 2000 3000
(integer) 2The Problem
3. The Redimo Way (Smart Mode)
Redimo displays Sorted Sets as a clean ranked table. Each row shows rank, member, and score in separate columns. Edit scores inline and watch members automatically reposition.
What Redimo Does for Sorted Sets:
- ●Ranked Table View: Three-column layout showing Rank | Member | Score. No mental parsing required.
- ●Ascending/Descending Toggle: Switch between low-to-high and high-to-low ordering with one click.
- ●Inline Score Editing: Click any score to edit it. The member automatically moves to its new position.
- ●Score Increment: Quickly increment or decrement scores without calculating new values manually.
- ●Virtual Scrolling: Browse leaderboards with millions of entries without lag.
CLI Pain Points
- • Interleaved member-score output
- • Manual rank calculation
- • 0-indexed confusion
- • Hard to compare scores visually
- • ZINCRBY requires current + delta
Redimo Solutions
- • Clean Rank | Member | Score table
- • Human-readable rankings (1st, 2nd...)
- • Asc/Desc toggle button
- • Inline score editing
- • Auto-repositioning on change
4. Leaderboard Patterns
Game Leaderboard
# Add player scores
ZADD leaderboard 1500 "player:alice" 2300 "player:bob" 3100 "player:diana"
# Get top 10 players
ZREVRANGE leaderboard 0 9 WITHSCORES
# Get a player's rank (1-indexed for display: add 1)
ZREVRANK leaderboard "player:bob" # Returns 1 (2nd place, 0-indexed)
# Update score when player wins
ZINCRBY leaderboard 100 "player:alice"
# Get players around a specific player (for context)
# If "player:bob" is rank 50, get ranks 45-55
ZREVRANGE leaderboard 45 55 WITHSCORESTime-Based Leaderboard (Daily)
# Use today's date in key
ZADD leaderboard:2024-12-25 1500 "player:alice"
# At midnight, archive and create new
RENAME leaderboard:2024-12-25 leaderboard:archive:2024-12-25
# Weekly leaderboard: union of daily scores
ZUNIONSTORE leaderboard:week:52 7 \
leaderboard:2024-12-23 leaderboard:2024-12-24 \
leaderboard:2024-12-25 ...
# Monthly top players: intersection keeps only consistent players
ZINTERSTORE consistent:players 30 \
leaderboard:2024-12-01 leaderboard:2024-12-02 ...5. Priority Queue Pattern
Sorted Sets make excellent priority queues. Use score as priority (or timestamp for delayed jobs):
Priority Queue
# Add jobs with priority (lower = higher priority)
ZADD jobs:queue 1 "critical-alert" 5 "send-email" 10 "cleanup-logs"
# Get highest priority job (lowest score)
ZRANGE jobs:queue 0 0
# Returns: "critical-alert"
# Process and remove job atomically
ZPOPMIN jobs:queue
# Returns: ["critical-alert", "1"]
# Add job with timestamp for delayed execution
ZADD jobs:delayed 1703520000 "send-reminder" # Unix timestamp
# Get all jobs ready to execute (score <= now)
ZRANGEBYSCORE jobs:delayed 0 1703520000Rate Limiting with Sliding Window
# Record each request with timestamp as score
ZADD rate:user:1001 1703520001 "req:1" 1703520002 "req:2" 1703520003 "req:3"
# Remove old entries (older than 1 minute)
ZREMRANGEBYSCORE rate:user:1001 0 (1703520001-60)
# Count requests in last minute
ZCOUNT rate:user:1001 (now-60) now
# If count > limit, reject request6. Advanced Sorted Set Operations
| Command | Description | Use Case |
|---|---|---|
ZUNIONSTORE | Union multiple ZSets, sum/min/max scores | Aggregate daily → weekly leaderboards |
ZINTERSTORE | Intersect multiple ZSets | Find players active in all periods |
ZRANGEBYSCORE | Get members by score range | Jobs ready for execution |
ZLEXRANGE | Lexicographic range (same score) | Autocomplete suggestions |
ZPOPMIN/ZPOPMAX | Pop lowest/highest score member | Priority queue consumption |
Aggregate Leaderboards
# Daily leaderboards
ZADD daily:2024-12-23 100 "alice" 200 "bob"
ZADD daily:2024-12-24 150 "alice" 100 "bob"
ZADD daily:2024-12-25 200 "alice" 300 "bob"
# Weekly aggregate (SUM scores)
ZUNIONSTORE weekly:52 3 daily:2024-12-23 daily:2024-12-24 daily:2024-12-25
# Check result
ZRANGE weekly:52 0 -1 WITHSCORES
# alice: 450, bob: 600
# Alternative: use MAX instead of SUM
ZUNIONSTORE weekly:best 3 daily:2024-12-23 daily:2024-12-24 daily:2024-12-25 AGGREGATE MAX7. Pro Tips
Score Precision
Useful Sorted Set Commands
# Get member count in score range
ZCOUNT leaderboard 1000 2000
# Remove by rank range
ZREMRANGEBYRANK leaderboard 0 9 # Remove bottom 10
# Remove by score range
ZREMRANGEBYSCORE leaderboard -inf 500 # Remove scores below 500
# Scan large sorted sets
ZSCAN leaderboard 0 MATCH "player:*" COUNT 100
# Block until element available (Redis 5.0+)
BZPOPMIN job:queue 30 # Wait up to 30 secondsRedimo Bonus
Ready to Visualize?
Stop parsing interleaved scores in your terminal.
Download Redimo and see your leaderboards as beautiful ranked tables.