Scan Iterators

July 1, 2026 · View on GitHub

:warning: The scan iterators API in v5 has breaking changes from the previous version. For more details, refer to the v4-to-v5 guide.

SCAN results can be looped over using async iterators:

for await (const keys of client.scanIterator()) {
  const values = await client.mGet(keys);
}

:warning: keyPrefix gotcha: When the client is configured with a keyPrefix, scanIterator yields the already-prefixed keys as stored on the server (replies are never un-prefixed). Passing them straight back into a key-prefixing command — like the mGet(keys) above — prefixes them a second time. For example, with keyPrefix: 'app:' a yielded 'app:foo' becomes 'app:app:foo', so the mGet silently reads the wrong keys. Strip the prefix before reusing the keys, or read them with a separate client that has no keyPrefix. (This affects only scanIterator; HSCAN/SSCAN/ZSCAN yield fields/members, which are not keys.)

This works with HSCAN, SSCAN, and ZSCAN too:

for await (const entries of client.hScanIterator('hash')) {}
for await (const members of client.sScanIterator('set')) {}
for await (const membersWithScores of client.zScanIterator('sorted-set')) {}

You can override the default options by providing a configuration object:

client.scanIterator({
  cursor: '0', // optional, defaults to '0'
  TYPE: 'string', // `SCAN` only
  MATCH: 'patter*',
  COUNT: 100
});