Description
Iterates the set of keys in the database using a cursor-based iterator. Unlike KEYS, SCAN doesn’t block the server and is safe to use in production.
Method Signatures
// Basic scan
scan ( cursor : string | number ): Promise < [ string , string []] >
// Scan with options (standard)
scan (
cursor : string | number ,
opts : ScanCommandOptionsStandard
): Promise < [ string , string []] >
// Scan with type information
scan (
cursor : string | number ,
opts : ScanCommandOptionsWithType
): Promise < [ string , { key: string ; type : string }[]] >
Parameters
The cursor position. Use "0" or 0 to start a new iteration.
Optional configuration object: Pattern to filter keys (glob-style pattern like "user:*")
Hint for number of keys to return per iteration (default: 10). Redis may return more or fewer keys.
Filter by key type: "string", "list", "set", "zset", or "hash"
When true, includes the type of each key in the result. Changes return type to include type information.
Return Value
result
[string, string[]] | [string, { key: string; type: string }[]]
A tuple containing:
Next cursor - Use this value in the next scan call. When "0", iteration is complete.
Keys - Array of matching keys (or objects with key and type if withType: true)
Examples
Basic iteration
let cursor = "0" ;
const allKeys : string [] = [];
do {
const [ nextCursor , keys ] = await redis . scan ( cursor );
allKeys . push ( ... keys );
cursor = nextCursor ;
} while ( cursor !== "0" );
console . log ( allKeys );
Scan with pattern matching
let cursor = "0" ;
const userKeys : string [] = [];
do {
const [ nextCursor , keys ] = await redis . scan ( cursor , {
match: "user:*"
});
userKeys . push ( ... keys );
cursor = nextCursor ;
} while ( cursor !== "0" );
console . log ( userKeys );
Scan with count hint
const [ cursor , keys ] = await redis . scan ( "0" , {
count: 100 // Request approximately 100 keys per iteration
});
console . log ( `Found ${ keys . length } keys, next cursor: ${ cursor } ` );
Filter by key type
let cursor = "0" ;
const stringKeys : string [] = [];
do {
const [ nextCursor , keys ] = await redis . scan ( cursor , {
type: "string"
});
stringKeys . push ( ... keys );
cursor = nextCursor ;
} while ( cursor !== "0" );
console . log ( stringKeys );
let cursor = "0" ;
do {
const [ nextCursor , items ] = await redis . scan ( cursor , {
withType: true
});
items . forEach (({ key , type }) => {
console . log ( ` ${ key } is a ${ type } ` );
});
cursor = nextCursor ;
} while ( cursor !== "0" );
Combine options
const [ cursor , items ] = await redis . scan ( "0" , {
match: "user:*" ,
count: 50 ,
withType: true
});
items . forEach (({ key , type }) => {
console . log ( ` ${ key } ( ${ type } )` );
});
Single-pass scan
// Get first batch of keys
const [ cursor , keys ] = await redis . scan ( "0" );
console . log ( keys );
// If cursor is "0", we've seen all keys
// Otherwise, there are more keys to fetch
if ( cursor !== "0" ) {
console . log ( "More keys available" );
}
Cursor-Based Iteration
The SCAN command uses cursor-based iteration:
Start with cursor "0"
Call scan(cursor) and receive [nextCursor, keys]
Process the keys
If nextCursor is "0", iteration is complete
Otherwise, call scan(nextCursor) and repeat
The cursor is opaque - don’t parse or manipulate it. Always use the cursor returned from the previous call.
Guarantees and Characteristics
Full iteration guarantee : A key that exists from start to finish will be returned
No duplicates guarantee : A key that is never modified will be returned only once
Safe for production : Non-blocking, suitable for large databases
Variable results : The number of keys returned per call may vary
Pattern matching : Filtering happens after fetching, so you may get empty results
See Also
keys - Get all keys matching a pattern (blocking)
type - Get the type of a key