SCAN for safe key iteration in Redis - Time & Space Complexity
When working with many keys in Redis, it's important to know how long it takes to look through them safely.
We want to understand how the time to scan keys grows as the number of keys increases.
Analyze the time complexity of the following Redis SCAN command usage.
local cursor = "0"
repeat
local result = redis.call('SCAN', cursor, 'COUNT', 100)
cursor = result[1]
local keys = result[2]
-- process keys here
until cursor == "0"
This code safely iterates over all keys in the database in small batches without blocking Redis.
Look for repeated actions in the code.
- Primary operation: Calling SCAN repeatedly to get batches of keys.
- How many times: The number of calls depends on total keys divided by batch size.
As the number of keys grows, the number of SCAN calls grows roughly in proportion.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 1 call (small number of keys) |
| 100 | About 1 call (batch size covers all keys) |
| 1000 | About 10 calls (100 keys per call) |
Pattern observation: The number of SCAN calls grows linearly with the number of keys divided by batch size.
Time Complexity: O(n)
This means the time to scan all keys grows roughly in direct proportion to how many keys there are.
[X] Wrong: "SCAN returns all keys in one call quickly."
[OK] Correct: SCAN returns keys in small batches to avoid blocking, so multiple calls are needed to get all keys.
Understanding how SCAN works and its time behavior shows you can handle large data safely without slowing down the system.
What if we changed the COUNT value to a much larger number? How would the time complexity change?
Practice
SCAN over KEYS in Redis for iterating keys?Solution
Step 1: Understand
KEYSbehaviorKEYSreturns all matching keys at once and blocks Redis during execution.Step 2: Understand
SCANbehaviorSCANreturns keys in small batches without blocking Redis, allowing safe iteration.Final Answer:
SCANdoes not block Redis and returns keys in batches. -> Option DQuick Check:
Safe iteration =SCANnon-blocking [OK]
SCAN is non-blocking, KEYS blocks [OK]- Thinking
SCANreturns all keys at once - Confusing
SCANwith key deletion - Assuming
SCANonly works on sorted sets
SCAN iteration from the beginning in Redis CLI?Solution
Step 1: Identify the starting cursor for SCAN
TheSCANcommand requires a cursor argument; starting cursor is always0.Step 2: Check options for correct cursor
SCAN 0starts iteration from the beginning; other options are invalid.Final Answer:
SCAN 0 -> Option BQuick Check:
Start cursor = 0 [OK]
SCAN with cursor 0 [OK]- Starting with cursor 1 instead of 0
- Using wildcard * as cursor
- Using invalid strings like 'start'
SCAN command?
SET user:1 Alice SET user:2 Bob SET admin:1 Carol SCAN 0 MATCH user:*
Solution
Step 1: Understand
TheSCANwith MATCHMATCH user:*filters keys starting with 'user:'. So keys 'user:1' and 'user:2' match; 'admin:1' does not.Step 2: Understand
SCANoutput formatSCANreturns a two-element array: a cursor (string) and a list of keys matching the pattern in this batch. Cursor is not necessarily 0 unless iteration is complete.Final Answer:
[cursor, ["user:1", "user:2"]] -> Option AQuick Check:
Filtered keys = user keys only [OK]
- Expecting cursor 0 on first SCAN call
- Including keys not matching pattern
- Confusing cursor with count
SCAN 0 MATCH user:*But you notice it returns only a partial list of keys matching the pattern. What is the likely mistake?
Solution
Step 1: Understand SCAN iteration process
SCANreturns a cursor and a batch of keys; to get all keys, you must repeatSCANwith the new cursor until it returns 0.Step 2: Identify the mistake
RunningSCAN 0 MATCH user:*only once returns partial keys; not looping causes incomplete results.Final Answer:
Not repeating SCAN with the returned cursor until it returns 0. -> Option AQuick Check:
Repeat SCAN until cursor 0 [OK]
- Expecting all keys in one SCAN call
- Misusing MATCH pattern syntax
- Starting with wrong cursor
session: in Redis but avoid blocking the server. You also want to limit each batch to about 10 keys. Which command sequence correctly achieves this?Solution
Step 1: Use SCAN with MATCH and COUNT
To filter keys starting with 'session:' and limit batch size, useMATCH session:*andCOUNT 10.Step 2: Repeat SCAN calls until cursor is 0
Iterate by passing the returned cursor each time until it returns 0 to get all keys safely without blocking.Final Answer:
RepeatSCAN cursor MATCH session:* COUNT 10until cursor returns 0. -> Option CQuick Check:
Safe iteration + filter + batch size = RepeatSCAN cursor MATCH session:* COUNT 10until cursor returns 0. [OK]
- Using KEYS which blocks Redis
- Not looping SCAN calls
- Omitting MATCH or COUNT when needed
Ready to prove it?
Pass the test and this pattern moves unknown
