Where the open source database community meets: Use code PERCONA75 and secure your spot for Percona Live.  Register

Manually Migrate Hash Slots in a Valkey/Redis Cluster

May 20, 2026
Author
Hieu Nguyen
Share this Post:

This article explains how to manually migrate hash slots in Valkey/Redis clusters to expand your deployment with minimal disruption to availability.

Note: Valkey 9.0 introduces the Atomic Slot Migration (ASM) feature, which significantly improves migration speed (up to 9.52 times faster) and reliability, while reducing migration complexity. So you should use ASM instead if you are using Valkey version 9.0 and later. You can read more about ASM in the Valkey’s community blog.

Refresher on hash slots

Valkey and Redis clusters partition their keyspace into 16,384 hash slots. Each key is assigned to a slot based on the CRC16 hash of its name (or hashtag), ensuring consistent and deterministic routing across cluster nodes:

So, for example, the command SET hello world will store the key hello in slot 866.

Accessing keys in different slots

Because hash slots in Valkey/Redis can be located on different processes, if you access multiple slots in a single command, the cluster would have to coordinate between nodes. This can impact cluster performance and data consistency, as nodes can fail while processing a command. So, to keep things simple and fast, Valkey/Redis will disallow accessing keys that hash to different slots.

You can read more about distributing data in Valkey/Redis cluster in my colleague Agustin’s blog post.

Why do you need to migrate hash slots?

As your dataset grows, your Valkey/Redis cluster may not have enough memory to hold all the data; or the resource utilization between nodes is not evenly distributed. To address these issues, you might need to add more nodes to the cluster, or move the hash slots around so that data doesn’t get evicted, and no nodes are under/overutilized.

How the slot migration process works

The slot migration process can be roughly divided into 3 steps:

1. Update the hash slot’s state so that clients can know where to get the keys during the migration stage:

2. MIGRATE the keys in the hash slot to the new owner:

3. Update the hash slot’s metadata to reflect the new ownership:

What happens when the hash slot is accessed during migration

During hash slot migration, if a command accesses keys stored in the migrating slot, the instance will first check its local hash table. If the keys are not found locally, the client will receive an ASK redirection to the target node. Unlike MOVED (which also tells the client to retry requests at another node), an ASK redirection is meant to be temporary; it will not update the client’s slot cache and affects only a single request. So, when you re-run the same request, even if you are on the correct node, you will still get redirected:

Commands executed during migration may fail if they access keys that are distributed across different nodes. In this case, the command will encounter the same limitation as a CROSSSLOT error, because all keys involved in the operation must reside on the same instance:

If the target node is the one receiving commands, the flow is much easier. It just checks if you are following an ASK redirection. If so, the command will be processed normally. If not, then the node will respond with -ASK and direct you to the original owner:

So, during the slot migration, your request will be redirected at most twice, first to the source node (since it is still registered as the owner of the hash slot), then to the target node if the keys are not found on the source:

Why using valkey-cli --cluster rebalance won’t work for all cases

Depending on your application’s key pattern, the number of keys each slot holds can vary, and a slot might have a disproportionate number of keys (the hot-slot problem). And, the --cluster rebalance command only attempts to evenly distribute the number of slots each node has:

So, using --cluster rebalance could migrate all hot slots to the same node, further exacerbating the issue.

How to manually migrate a hash slot to a different node

1. Gather usage statistics on the slot

To find the list of big hash slots, we can use CLUSTER SLOT-STATS, which provides details for each slot (number of keys, CPU time, and network I/O).

Note: to display stats other than key-count, the config cluster-slot-stats-enabled needs to be set. The config can be modified during runtime, but remember to set it for all nodes in the cluster:

To find which node the hash slot belongs to, we can use the CLUSTER SLOTS command. In the example below, node 127.0.0.1:30001 holds slots 0-5460, 127.0.0.1:30003 holds slots 10923-16383:

To find the nodes’ IDs, use the CLUSTER NODES command. The ID of each node is shown in the first column:

2. Update slot metadata (MIGRATING status)

After collecting statistics for each hash slot, we should have a clear understanding of the data size and usage patterns for each slot. Based on this information, we can decide which underutilized node a slot should be migrated to. This helps ensure that resource utilization is evenly balanced across all nodes in the cluster.

On the target node, execute CLUSTER SETSLOT <SLOT> IMPORTING <SOURCE-NODE-ID>

On the source node, execute CLUSTER SETSLOT <SLOT> MIGRATING <TARGET-NODE-ID>

When set correctly, commands that create new keys in the hash slot will be directed to the target node:

Note: remember to double-check the node IDs used in the commands. Currently, Valkey/Redis does not check if the node ID provided is the actual owner of the hash slot, so the (wrong) commands like below will still be able to execute successfully:

So, when a new key is created (or a migrated key is updated), the request still goes to the original owner, instead of the target node:

And if you attempt to migrate a duplicated key, you will get the following error:

Since valkey-cli --cluster check will still report the correct status, debugging this issue will be pretty confusing:

I have created a Pull Request to the Valkey project, disallowing the command CLUSTER SETSLOT MIGRATING/IMPORTING to point to itself, so future versions of Valkey should not encounter this issue.

3. Migrate keys in the slot

After updating the slots’ state, we need to perform the actual data migration in those slots. We need to get the list of keys in the migrating slot using CLUSTER GETKEYSINSLOT, then execute the MIGRATE command on the found keys.

The script below will get and migrate the keys in DB 0 in slot 5970 from node 127.0.0.1:30002 to 127.0.0.1:30001 in a batch of 10 keys, with the timeout for each MIGRATE command being 5000 milliseconds:

The migration is finished when CLUSTER GETKEYSINSLOT returns an empty array:

4. Update slot ownership

After the keys migration is completed, update the slot’s metadata on the original and new node using CLUSTER SETSLOT <SLOT> NODE <TARGET-NODE-ID> to reflect the new ownership:

It will take a little while for the cluster to agree on the new slot distribution, as the metadata is propagated via the gossip protocol.

5. Validate the cluster’s state

Validate the cluster’s hash slots distribution with valkey-cli –cluster check to ensure that all slots are covered:

We can see that the migration is successful, with all 16384 hash slots covered, and the slot distribution is reported correctly, with node 127.0.0.1:30001 having 1 more slot than the rest.

Conclusion

In this article, we learned how to perform manual hash slot migration to balance/expand a Valkey/Redis cluster. And while manual hash slot migration is a necessary process to resolve hot-slot issues that automated rebalancing cannot, users on Valkey 9.0 and later should leverage the faster, more reliable Atomic Slot Migration (ASM) feature.

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Far
Enough.

Said no pioneer ever.
MySQL, PostgreSQL, InnoDB, MariaDB, MongoDB and Kubernetes are trademarks for their respective owners.
© 2026 Percona All Rights Reserved