Why KEYS Is Dangerous in Redis and How SCAN or Indexing Solves It
The article explains why using the KEYS command in Redis is a blocking operation that can cripple production systems, demonstrates the safe, incremental SCAN approach, and proposes an index‑based architecture or replica scans for high‑frequency or offline key‑lookup scenarios.
Level 1: Wrong or risky answer (KEYS)
Using KEYS "your_prefix:*" directly scans the entire keyspace. It is a blocking operation because Redis processes commands single‑threaded; while KEYS traverses all keys, no other client request can be served.
Single‑threaded nature: All other client requests wait until KEYS finishes.
Full scan: KEYS iterates over every key (e.g., 100 million) to find matches, causing the server to be unresponsive.
Production disaster: Running KEYS on a large instance can freeze Redis for seconds or minutes, leading to timeouts and cascading failures.
Conclusion: KEYS should only be used for debugging or when the total key count is tiny; it must never be used in a production environment with large datasets.
Level 2: Standard and safe answer (SCAN)
The SCAN command is designed to avoid the blocking problem of KEYS. It iterates incrementally, returning a cursor and a small batch of keys each call.
# First call, start from cursor 0
SCAN 0 MATCH "your_prefix:*" COUNT 1000
# Example result
# 1) "1762" <-- next cursor
# 2) 1) "your_prefix:key1"
# 2) "your_prefix:key2"
# ... (a batch of keys)
# Subsequent call using the new cursor
SCAN 1762 MATCH "your_prefix:*" COUNT 1000
# Repeat until the returned cursor is "0"Non‑blocking incremental iteration: Each SCAN call scans only a small portion of the dataset and returns a cursor for the next iteration.
Minimal impact on business: The operation is O(1) per call and does not lock the main thread.
COUNT parameter: Provides a hint for how many keys to return per iteration; it is not exact.
In client code (Java, Python, Go, etc.) you loop until the cursor returned is “0”, aggregating the results.
Level 3: Better architectural design (indexing)
To eliminate the need for any scan, maintain an auxiliary index (a Set or Hash) that records the unique identifiers of keys with the target prefix.
Write path
When creating a key, e.g., SET "your_prefix:123" "value", also add the identifier to a fixed Set: SADD "index:your_prefix" "123".
Read path
Retrieve all members of the index with SMEMBERS "index:your_prefix". This returns the identifiers in O(N) where N is the size of the Set, not the total key count.
Delete path
When deleting the original key, also remove the identifier from the index: DEL "your_prefix:123" and SREM "index:your_prefix" "123".
Pros: Extremely fast look‑ups, avoids any full‑key scan.
Cons: Increases write/delete complexity and consumes extra memory for the index.
Alternative: Run scans on a replica
If the operation is low‑frequency and only needed for offline analysis, execute KEYS or SCAN on a Redis replica. This isolates the load from the primary node, preventing impact on production traffic.
Interview answer summary
Never use KEYS "your_prefix:*" in production because it blocks the server. Prefer SCAN with a loop and appropriate COUNT to safely enumerate matching keys. For frequent look‑ups, design an index using a Set (or Hash) to retrieve keys instantly, or run scans on a replica to isolate risk.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
dbaplus Community
Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.
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.
