Using Redis SCAN to Enumerate Keys Safely and Avoid Server Blocking
The article explains why the KEYS command can cripple a Redis instance with millions of keys, analyzes its O(n) blocking behavior, and demonstrates how to use the incremental SCAN command with MATCH and COUNT options to safely iterate key prefixes without affecting performance.
Sometimes you need to inspect the usage of Redis in production, especially to list keys with a certain prefix. This guide shows how to do that safely.
Incident : The user token cache uses keys like user_token:userid . To check the number of logged‑in users, the operations team ran keys user_token* . Because the system had millions of keys, the KEYS command blocked the single‑threaded Redis server, causing a near‑deadlock.
Analysis : KEYS scans the entire keyspace with O(n) complexity; the more keys, the longer it takes. Since Redis processes commands sequentially, other commands must wait for KEYS to finish, leading to severe latency.
Solution : Use the SCAN command instead of KEYS. SCAN iterates the keyspace incrementally using a cursor, so it does not block the server. Its characteristics include:
Complexity remains O(n) but is performed in small steps.
The optional COUNT argument controls how many slots are examined per iteration.
Supports pattern matching with MATCH , just like KEYS.
No server‑side state is kept; the cursor is the only state returned to the client.
Results may contain duplicates, so the client must deduplicate.
A cursor value of zero indicates the iteration is complete.
SCAN command syntax
SCAN cursor [MATCH pattern] [COUNT count]Explanation
SCAN returns a small subset of keys each call, preventing Redis from freezing. The command returns a new cursor; start with 0 and continue until the cursor returned is 0.
Example
redis> scan 0 match user_token* count 5
1) "6"
2) "user_token:1000"
3) "user_token:1001"
4) "user_token:1010"
5) "user_token:2300"
6) "user_token:1389"From cursor 0 the command returns cursor 6 and a batch of matching keys. Continue scanning from cursor 6:
redis> scan 6 match user_token* count 5
1) "10"
2) "user_token:3100"
3) "user_token:1201"
4) "user_token:1410"
5) "user_token:5300"
6) "user_token:3389"Iterate until the returned cursor becomes 0.
Conclusion : SCAN is a common interview topic and a practical tool for large Redis deployments. Using KEYS on massive datasets can severely impact performance, while SCAN provides a non‑blocking way to enumerate keys.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
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.