# CLUSTER MIGRATESLOTS

> Move slot ranges to other primaries in one step, with no ASK redirects and no half-moved slots.

URL: https://docs.hotkv.com/commands/cluster-migrateslots/

```
CLUSTER MIGRATESLOTS SLOTSRANGE start-slot end-slot [start-slot end-slot ...] NODE node-id [SLOTSRANGE start-slot end-slot [start-slot end-slot ...] NODE node-id ...]
```

- Group: Cluster
- Complexity: O(N) where N is the number of keys in the slots
- HotKV Cloud: not available
- On-Premise: no license needed

`CLUSTER MIGRATESLOTS` moves hash slots, with every key in them and the AI
data HotKV keeps by slot, from the primary you send it to another primary.
It is the atomic slot migration of Valkey 9: the target receives a copy of
the slots and every write made to them meanwhile, and the slots change owner
only when the target holds all of it. Clients never see a half-moved slot,
so there are no `ASK` redirects and no per-key `MIGRATE`.

Send it to the primary that owns the slots, and name the target primary by
its node ID. The command only starts the move and replies `OK` at once. Watch
the move with [`CLUSTER GETSLOTMIGRATIONS`](https://docs.hotkv.com/commands/cluster-getslotmigrations/index.md)
and stop it with
[`CLUSTER CANCELSLOTMIGRATIONS`](https://docs.hotkv.com/commands/cluster-cancelslotmigrations/index.md).
[Scaling](https://docs.hotkv.com/clustering/scaling/index.md) compares this command with the other ways of
moving slots.

## Options

| Part | Meaning |
| --- | --- |
| `SLOTSRANGE start-slot end-slot ...` | One or more inclusive slot ranges, as pairs. A single slot is a range with the same start and end. Every slot must belong to the receiving node. |
| `NODE node-id` | The primary that receives the slots in the `SLOTSRANGE` pairs before it. |

Each `SLOTSRANGE ... NODE ...` group is one migration, and the migrations of
one command start together and run side by side. Their slots must not
overlap. To send slots to several nodes with one command, repeat the group.

## How a migration runs

1. The source connects to the target's client port and signs in with
   `masterauth` when it is set. When nodes have `requirepass`, give every node
   the same `masterauth`, or the migration fails with `Received error during
   handshake to target: -NOAUTH Authentication required.`
2. The target receives the keys of the slots in every database, the AI data
   of the slots, and then the writes the source accepts for them. The source
   keeps serving the slots meanwhile. A client that asks the target for a key
   in the slots gets `MOVED` to the source.
3. When the target has caught up, the source holds writes to the slots for a
   moment and the target takes them over. From then on clients get `MOVED`
   from the source. The source then deletes its copy.

If anything goes wrong the slots stay with the source, the target deletes
what it received, and the migration shows `failed` in `CLUSTER
GETSLOTMIGRATIONS` with the reason in `message`. Failures you can cause on
purpose or meet by accident: a lost connection between the nodes, a missing
or wrong password, a target that runs out of memory (`Ran out of memory (OOM)
during slot import`), and `CLUSTER CANCELSLOTMIGRATIONS`. A failed migration
is not retried; run the command again.

While a migration of a slot runs, [`CLUSTER SETSLOT`](https://docs.hotkv.com/commands/cluster-setslot/index.md)
on that slot is refused, and `CLUSTER MIGRATESLOTS` is refused while a slot is
open by hand.

## Return value

| Case | RESP2 | RESP3 |
| --- | --- | --- |
| Migrations started | Simple string `OK` | Simple string `OK` |

Errors, in the order the command checks:

| Case | Error |
| --- | --- |
| Not enough arguments | `ERR wrong number of arguments for 'cluster\|migrateslots' command` |
| Sent to a replica | `ERR Slot migration can only be used on primary nodes.` |
| A slot is `IMPORTING` on this node | `ERR Slots are being manually imported` |
| A slot is `MIGRATING` from this node | `ERR Slots are being manually migrated` |
| A word other than `SLOTSRANGE` or `NODE` where one is expected, or `NODE` missing | `ERR syntax error` |
| A range with a start and no end | `ERR No end slot for final slot range` |
| A slot outside 0 to 16383 | `ERR Invalid or out of range slot` |
| A range that starts after it ends | `ERR Start slot number <start> is greater than end slot number <end>.` |
| A slot no node serves | `ERR Slot <slot> has no node served.` |
| The slots of one group are owned by more than one shard | `ERR Requested slots span multiple shards` |
| The receiving node does not own the slots | `ERR Slots are not served by this node.` |
| A slot is already being exported | `ERR I am already migrating slot <slot>.` |
| Two groups share slots | `ERR Slot ranges in migrations overlap` |
| The node ID is not 40 characters | `ERR Invalid node name: <name>` |
| The node ID is not a known node | `ERR Unknown node name: <name>` |
| The target is the receiving node | `ERR Target node can not be this node.` |
| Cluster mode is off | `ERR This instance has cluster support disabled` |

## Examples

The ID `49a04a...` is the primary on port 7001 and `80eaf7...` the primary on
port 7002. Move one range, then two ranges, then two groups with different
targets:

```
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 0 99 NODE 49a04a859cbe2f18b168fdff41f4f2346045f9e3
OK
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 100 149 200 249 NODE 49a04a859cbe2f18b168fdff41f4f2346045f9e3
OK
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 300 399 NODE 49a04a859cbe2f18b168fdff41f4f2346045f9e3 SLOTSRANGE 400 499 NODE 80eaf747c8dde56484b36ddd5418b3098c6d3828
OK
```

Refusals:

```
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 6000 6001 NODE 49a04a859cbe2f18b168fdff41f4f2346045f9e3
(error) ERR Slots are not served by this node.
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 150 160 NODE ea0c1bd255fc04ab7dfc3aabf682cb8f64f84cba
(error) ERR Target node can not be this node.
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 150 160 NODE 0000000000000000000000000000000000000000
(error) ERR Unknown node name: 0000000000000000000000000000000000000000
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 150 160 NODE 49a04a859cbe2f18b168fdff41f4f2346045f9e3 SLOTSRANGE 155 170 NODE 80eaf747c8dde56484b36ddd5418b3098c6d3828
(error) ERR Slot ranges in migrations overlap
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 5400 5500 NODE 49a04a859cbe2f18b168fdff41f4f2346045f9e3
(error) ERR Requested slots span multiple shards
127.0.0.1:7004> CLUSTER MIGRATESLOTS SLOTSRANGE 500 510 NODE 49a04a859cbe2f18b168fdff41f4f2346045f9e3
(error) ERR Slot migration can only be used on primary nodes.
127.0.0.1:7000> CLUSTER SETSLOT 160 MIGRATING 49a04a859cbe2f18b168fdff41f4f2346045f9e3
OK
127.0.0.1:7000> CLUSTER MIGRATESLOTS SLOTSRANGE 150 199 NODE 49a04a859cbe2f18b168fdff41f4f2346045f9e3
(error) ERR Slots are being manually migrated
```

## Compatibility

The same command, arguments and error texts as Valkey 9, and
`valkey-cli --cluster reshard --cluster-use-atomic-slot-migration` drives it.
Redis 8 has no such command: its atomic migration is started on the target
with [`CLUSTER MIGRATION IMPORT`](https://docs.hotkv.com/commands/cluster-migration/index.md).

## See also

[CLUSTER GETSLOTMIGRATIONS](https://docs.hotkv.com/commands/cluster-getslotmigrations/index.md),
[CLUSTER CANCELSLOTMIGRATIONS](https://docs.hotkv.com/commands/cluster-cancelslotmigrations/index.md),
[CLUSTER MIGRATION](https://docs.hotkv.com/commands/cluster-migration/index.md),
[CLUSTER SETSLOT](https://docs.hotkv.com/commands/cluster-setslot/index.md),
[Scaling a cluster](https://docs.hotkv.com/clustering/scaling/index.md)