Skip to content

Commit 8e9de32

Browse files
committed
Improve documentation for scan_keys and scan_all_keys functions
- Add clear warnings about partial results in scan_keys - Include usage examples for better AI client understanding - Add memory usage warning for scan_all_keys with large datasets - Address maintainer feedback about potential client confusion
1 parent 9ef8caa commit 8e9de32

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

src/tools/misc.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ async def scan_keys(pattern: str = "*", count: int = 100, cursor: int = 0) -> di
102102
"""
103103
Scan keys in the Redis database using the SCAN command (non-blocking, production-safe).
104104
105+
⚠️ IMPORTANT: This returns PARTIAL results from one iteration. Use scan_all_keys()
106+
to get ALL matching keys, or call this function multiple times with the returned cursor
107+
until cursor becomes 0.
108+
105109
The SCAN command iterates through the keyspace in small chunks, making it safe to use
106110
on large databases without blocking other operations.
107111
@@ -111,13 +115,20 @@ async def scan_keys(pattern: str = "*", count: int = 100, cursor: int = 0) -> di
111115
count: Hint for the number of keys to return per iteration (default 100).
112116
Redis may return more or fewer keys than this hint.
113117
cursor: The cursor position to start scanning from (0 to start from beginning).
118+
To continue scanning, use the cursor value returned from previous call.
114119
115120
Returns:
116121
A dictionary containing:
117122
- 'cursor': Next cursor position (0 means scan is complete)
118-
- 'keys': List of keys found in this iteration
123+
- 'keys': List of keys found in this iteration (PARTIAL RESULTS)
119124
- 'total_scanned': Number of keys returned in this batch
125+
- 'scan_complete': Boolean indicating if scan is finished
120126
Or an error message if something goes wrong.
127+
128+
Example usage:
129+
First call: scan_keys("user:*") -> returns cursor=1234, keys=[...], scan_complete=False
130+
Next call: scan_keys("user:*", cursor=1234) -> continues from where it left off
131+
Final call: returns cursor=0, scan_complete=True when done
121132
"""
122133
try:
123134
r = RedisConnectionManager.get_connection()
@@ -143,6 +154,9 @@ async def scan_all_keys(pattern: str = "*", batch_size: int = 100) -> list:
143154
144155
This function automatically handles the SCAN cursor iteration to collect all matching keys.
145156
It's safer than KEYS * for large databases but will still collect all results in memory.
157+
158+
⚠️ WARNING: With very large datasets (millions of keys), this may consume significant memory.
159+
For large-scale operations, consider using scan_keys() with manual iteration instead.
146160
147161
Args:
148162
pattern: Pattern to match keys against (default is "*" for all keys).

0 commit comments

Comments
 (0)