SCAN-&-KEYS
KEYS finds all matching keys instantly but blocks Redis. SCAN iterates safely without blocking. Know when to use each - your production server depends on it.
You'll Learn
- KEYS vs SCAN trade-offs
- Pattern matching syntax
- Cursor-based iteration
- How Redimo handles large keyspaces
See Your Data, Not Terminal Text
Redimo visualizes every Redis data type beautifully. Edit inline, undo mistakes, stay safe in production.
1. KEYS vs SCAN
KEYS returns all matching keys in one call - fast but blocks Redis while scanning the entire keyspace. SCAN returns keys in batches using a cursor - slower but non-blocking.
The rule is simple: Never use KEYS in production. With 1 million keys, KEYS can block Redis for 100ms+. That's 100ms where no other client can be served. SCAN is always safe.
Syntax
# KEYS - find all matching keys (BLOCKING!)
KEYS pattern # Returns all matching keys at once
# SCAN - iterate through keys (non-blocking)
SCAN cursor [MATCH pattern] [COUNT hint] [TYPE type]
# Pattern wildcards:
# * matches any characters (including empty)
# ? matches exactly one character
# [ae] matches 'a' or 'e'
# [a-z] matches any lowercase letter
# [^a] matches any character except 'a'KEYS Dangers
- • Blocks Redis until complete
- • O(N) where N = total keys
- • Can cause timeouts for all clients
- • No way to stop once started
SCAN Advantages
- • Non-blocking iteration
- • Constant time per call
- • Works with any keyspace size
- • Can filter by type (Redis 6.0+)
2. The CLI Way (Hard Mode)
SCAN requires multiple iterations with manual cursor tracking. It's tedious and error-prone:
Using KEYS (Dangerous in Production)
127.0.0.1:6379> KEYS user:*
1) "user:1001"
2) "user:1002"
3) "user:1003"
... (imagine 100,000 more keys)
# Redis was blocked for 150ms while generating this list!
127.0.0.1:6379> KEYS session:*:data
1) "session:abc123:data"
2) "session:def456:data"Using SCAN (Production-Safe)
127.0.0.1:6379> SCAN 0 MATCH user:* COUNT 100
1) "13107" # Next cursor (not a count!)
2) 1) "user:5823"
2) "user:1204"
3) "user:9012"
... (approximately 100 keys, not exact)
127.0.0.1:6379> SCAN 13107 MATCH user:* COUNT 100
1) "26842" # Next cursor
2) 1) "user:3421"
2) "user:7890"
...
# Keep calling until cursor returns 0
127.0.0.1:6379> SCAN 26842 MATCH user:* COUNT 100
1) "0" # Iteration complete!
2) 1) "user:9999"
2) "user:4567"The Problem
3. The Redimo Way (Smart Mode)
Redimo uses SCAN automatically behind the scenes. Type a pattern in the search bar, see results instantly with type icons, TTL info, and folder organization. It handles millions of keys with virtual scrolling.
What Redimo Does for Key Discovery:
- ●Automatic SCAN: Pattern searches use SCAN internally. Your production Redis never blocks, no matter how many keys you have.
- ●Type Icons: Each key shows its type (string, hash, list, set, zset) with a visual icon. No need to run TYPE for each key.
- ●TTL Display: Keys with expiration show remaining time inline. Live countdown for keys about to expire.
- ●Folder Tree: Keys are organized by delimiter (default: colon) into a folder hierarchy. Navigate "user:1001:profile" as folders.
- ●Virtual Scrolling: Browse millions of keys without lag. The UI only renders visible rows.
CLI Pain Points
- • KEYS blocks production
- • SCAN needs cursor tracking
- • No type/TTL info in results
- • Flat list, no organization
- • Large results overflow terminal
Redimo Solutions
- • Safe SCAN under the hood
- • Pattern search bar
- • Type icons + TTL visible
- • Folder tree organization
- • Virtual scrolling for millions
4. Understanding SCAN
SCAN's cursor system is often misunderstood. Here's how it actually works:
The Cursor is NOT a Count
The cursor returned by SCAN is an opaque value representing a position in the hash table. Don't treat it as a page number or offset. Just pass it back to the next SCAN call.
COUNT is a Hint, Not a Limit
COUNT 100 tells Redis to scan approximately 100 hash slots. The actual number of keys returned varies. You might get 0 keys, or you might get 500.
Duplicates are Possible
If the hash table resizes during iteration, you might see some keys twice. Your application should handle duplicates (e.g., use a Set to collect results).
Cursor 0 Means Start/End
Start with cursor 0. When SCAN returns cursor 0, iteration is complete. Any other cursor value means there are more keys to scan.
Complete SCAN Iteration (Python)
import redis
r = redis.Redis()
cursor = 0
all_keys = set() # Use set to handle duplicates
while True:
cursor, keys = r.scan(cursor=cursor, match="user:*", count=100)
all_keys.update(keys)
if cursor == 0:
break
print(f"Found {len(all_keys)} keys")5. Pattern Matching Examples
Common Patterns
# All keys starting with "user:"
SCAN 0 MATCH user:*
# All keys ending with ":profile"
SCAN 0 MATCH *:profile
# User keys with 4-digit ID
SCAN 0 MATCH user:????
# Session keys with any middle segment
SCAN 0 MATCH session:*:data
# Keys with specific characters
SCAN 0 MATCH log:[we]* # log:warning, log:error (not log:info)
# Escape special characters with backslash
SCAN 0 MATCH user\:special\*nameFilter by Type (Redis 6.0+)
# Only find Hash keys
SCAN 0 MATCH user:* TYPE hash
# Only find List keys
SCAN 0 MATCH queue:* TYPE list
# Only find Set keys
SCAN 0 MATCH tags:* TYPE set
# Only find Sorted Set keys
SCAN 0 MATCH leaderboard:* TYPE zset
# Only find String keys
SCAN 0 MATCH cache:* TYPE string6. Pro Tips
HSCAN, SSCAN, ZSCAN
Collection-Specific Scans
# Iterate Hash fields
HSCAN user:1001 0 MATCH "email*" COUNT 100
# Iterate Set members
SSCAN tags:article:123 0 MATCH "tech*" COUNT 100
# Iterate Sorted Set members
ZSCAN leaderboard 0 MATCH "player:*" COUNT 100
# All return: [cursor, [results...]]SCAN is Stateless
Redimo Bonus
Ready to Browse?
Stop wrestling with SCAN cursors and pattern syntax.
Download Redimo and browse keys like a file explorer.