# CLUSTERSCAN

> Iterate over the keys of the whole cluster, slot by slot, with a cursor that goes from node to node.

URL: https://docs.hotkv.com/commands/clusterscan/

```
CLUSTERSCAN cursor [MATCH pattern] [COUNT count] [TYPE type] [SLOT slot]
```

- Group: Cluster
- HotKV Cloud: not available
- On-Premise: no license needed

`CLUSTERSCAN` walks the keys of the selected database across every primary of
a cluster, the way [SCAN](https://docs.hotkv.com/commands/scan/index.md) walks one node. You call it again
and again, each time with the cursor the previous call returned, and the
cursor leads from one node to the next: a cursor names the hash slot the scan
is in, so the command is routed to the node that serves that slot, and a
cluster-aware client (or `redis-cli -c`) follows the `MOVED` redirect when the
scan crosses to another node. Start with cursor `0`, and stop when the
cursor you get back is `0`.

A call goes on through the slots that one node serves, and visits about
`COUNT` keys before it returns, so a call may return few keys, none, or a
cursor in the middle of a slot. Every reply is valid: pass back the cursor you
were given, unchanged. In a cluster that does not change during the scan, each
key is returned once.

Pass the cursor `0` only to start. It names where to begin and returns no
keys: the first reply of a scan is an empty list with the cursor of the first
slot (`0-{06S}-0` is slot 0).

## Options

| Option | Effect |
| --- | --- |
| `MATCH pattern` | Return only the keys that match the glob-style pattern. Applied after the keys are visited, so a call can return an empty list and a non-zero cursor. When the pattern begins with a hash tag that closes before any wildcard, such as `{user:1000}*`, the scan starts in the slot of that tag. |
| `COUNT count` | About how many keys a call visits, counted before `MATCH` and `TYPE`. The default is 10. It must be 1 or more. |
| `TYPE type` | Return only the keys of this type (`string`, `hash`, `list`, `set`, `zset`, `stream`, ...). |
| `SLOT slot` | Scan one slot only (0 to 16383). The scan ends with cursor `0` when it has covered that slot. |

## Return value

An array of two elements, the same in RESP2 and RESP3:

1. The next cursor, as a bulk string. `0` means the scan is complete.
2. The keys found by this call, as an array of bulk strings (possibly empty).

Errors:

| Error | Cause |
| --- | --- |
| `ERR This instance has cluster support disabled` | The server is not in cluster mode. Use `SCAN`. |
| `ERR Invalid cursor` | The cursor is not `0` and not one a previous call returned. |
| `ERR Invalid or out of range slot` | `SLOT` is not a number from 0 to 16383. |
| `ERR SLOT option can only be specified once` | `SLOT` given twice. |
| `ERR Cursor slot mismatch with SLOT argument` | The cursor is in another slot than `SLOT`. |
| `ERR unknown type name 'name'` | `TYPE` names a type that does not exist. |
| `ERR syntax error` | An unknown option, or `COUNT` below 1. |
| `MOVED slot address` | The node you sent the call to does not serve the cursor's slot. A cluster-aware client follows it. |

## Examples

A scan of a three-primary cluster holding a few keys, with `redis-cli -c`
following the redirects. Cursor `0` starts the scan and returns no keys; each
call after it goes to the node that serves the slot in the cursor:

```
127.0.0.1:7000> CLUSTERSCAN 0 COUNT 100
-> Redirected to slot [13907] located at 127.0.0.1:7002
1) "0-{06S}-0"
2) (empty array)
127.0.0.1:7002> CLUSTERSCAN 0-{06S}-0 COUNT 100
-> Redirected to slot [0] located at 127.0.0.1:7000
1) "0-{8M}-0"
2) 1) "key:11"
   2) "user:1000"
   3) "key:4"
   4) "key:8"
127.0.0.1:7000> CLUSTERSCAN 0-{8M}-0 COUNT 100
-> Redirected to slot [5461] located at 127.0.0.1:7001
1) "0-{63n}-0"
2) 1) "key:10"
   2) "key:1"
   3) "key:5"
   4) "key:9"
   5) "profile:1"
   6) "key:2"
127.0.0.1:7001> CLUSTERSCAN 0-{63n}-0 COUNT 100
-> Redirected to slot [10923] located at 127.0.0.1:7002
1) "0"
2) 1) "key:6"
   2) "key:12"
   3) "key:3"
   4) "key:7"
```

A small `COUNT` cuts a call short in the middle of a slot, and the cursor says
where to go on. `MATCH` and `TYPE` filter what is returned:

```
127.0.0.1:7000> CLUSTERSCAN 0-{06S}-0 COUNT 2
1) "0gmX72-{5h1}-2724"
2) 1) "key:11"
   2) "user:1000"
127.0.0.1:7000> CLUSTERSCAN 0-{06S}-0 MATCH key:1* COUNT 100
1) "0-{8M}-0"
2) 1) "key:11"
127.0.0.1:7000> CLUSTERSCAN 0-{8M}-0 TYPE hash COUNT 100
-> Redirected to slot [5461] located at 127.0.0.1:7001
1) "0-{63n}-0"
2) 1) "profile:1"
```

`SLOT` limits the scan to one slot. The key `user:1000` is in slot 1649:

```
127.0.0.1:7001> CLUSTERSCAN 0 SLOT 1649
-> Redirected to slot [13907] located at 127.0.0.1:7002
1) "0-{bQs}-0"
2) (empty array)
127.0.0.1:7002> CLUSTERSCAN 0-{bQs}-0 SLOT 1649 COUNT 100
-> Redirected to slot [1649] located at 127.0.0.1:7000
1) "0"
2) 1) "user:1000"
```

Errors:

```
127.0.0.1:7000> CLUSTERSCAN abc
-> Redirected to slot [7638] located at 127.0.0.1:7001
(error) ERR Invalid cursor
127.0.0.1:7001> CLUSTERSCAN 0 SLOT 99999
-> Redirected to slot [13907] located at 127.0.0.1:7002
(error) ERR Invalid or out of range slot
127.0.0.1:7002> CLUSTERSCAN 0 SLOT 1 SLOT 2
(error) ERR SLOT option can only be specified once
127.0.0.1:7002> CLUSTERSCAN 0 TYPE nosuchtype
(error) ERR unknown type name 'nosuchtype'
127.0.0.1:7002> CLUSTERSCAN 0 COUNT 0
(error) ERR syntax error
127.0.0.1:7002> CLUSTERSCAN 0-{06S}-0 SLOT 5
-> Redirected to slot [0] located at 127.0.0.1:7000
(error) ERR Cursor slot mismatch with SLOT argument
```

On a server that is not a cluster:

```
127.0.0.1:6379> CLUSTERSCAN 0
(error) ERR This instance has cluster support disabled
```

To print every key, loop until the cursor is `0`. See
[Scanning and counting](https://docs.hotkv.com/clustering/keys-and-commands/index.md#counting-listing-and-scanning)
for a script.

## Compatibility

The command, options and errors follow Valkey 9.1's `CLUSTERSCAN`. `SCAN`,
`HSCAN`, `SSCAN` and `ZSCAN` take no `SLOT` option, and `SCAN` answers for the
node it is sent to only.

## See also

[SCAN](https://docs.hotkv.com/commands/scan/index.md), [KEYS](https://docs.hotkv.com/commands/keys/index.md), [DBSIZE](https://docs.hotkv.com/commands/dbsize/index.md),
[CLUSTER KEYSLOT](https://docs.hotkv.com/commands/cluster-keyslot/index.md),
[CLUSTER FLUSHSLOT](https://docs.hotkv.com/commands/cluster-flushslot/index.md)