migrating slots live, safely adding and removing nodes
A growing Redis Cluster sooner or later needs to move hash slots between nodes, take on new nodes, or remove old ones, all while the application keeps running uninterrupted. redis-cli --cluster reshard orchestrates this operation through the MIGRATING and IMPORTING state of individual slots, turning resharding into a controlled, live operation instead of a maintenance window.
Table of Contents
- 1. Why resharding becomes necessary
- 2. redis-cli --cluster reshard in detail
- 3. Slot migration step by step: MIGRATING and IMPORTING
- 4. Safely adding nodes
- 5. Safely removing nodes
- 6. Automated resharding and rebalancing
- 7. Recognizing and avoiding downtime risks
- 8. Monitoring during a resharding operation
- 9. Rollback strategies for a failed resharding operation
- 10. Summary
- 11. FAQ
1. Why resharding becomes necessary
Resharding describes moving hash slots between the nodes of an existing Redis Cluster after the fact. The need typically arises from three directions: part of the dataset grows faster than the rest and consumes a disproportionate amount of memory on its node, new nodes with more capacity are added and should take on a fair share of the load, or an existing node needs to be removed from the cluster, for example during a hardware migration, and its slots need to be relocated first.
The crucial difference from a classic database migration operation is that resharding in Redis Cluster is designed to work without downtime. During the migration of a single slot, both the source and target node remain reachable for reads and writes, the cluster protocol's MOVED and ASK redirects transparently route clients to the correct node, even while data is actively in motion.
It is important to understand that resharding is not an exceptional event but a normal, recurring part of operating a growing Redis Cluster. Teams that treat resharding as a rare, risky emergency operation instead of establishing it as a routine task regularly find themselves under unnecessary time pressure once a node actually hits its capacity limit. The following sections show how to perform resharding in a controlled, monitored way without risking data availability.
2. redis-cli --cluster reshard in detail
The redis-cli --cluster reshard command is the primary tool for manual, targeted resharding. It interactively asks for the number of slots to move, the target node, and the source nodes, and then takes over the entire orchestration of migrating individual slots, including every necessary intermediate step. For automated workflows, all parameters can also be passed directly as command line options without any interactive input.
Internally, --cluster reshard works slot by slot: for every slot to be migrated, it first determines all the keys it contains, puts the slot into the appropriate transitional state on both source and target node, and migrates the keys individually via the MIGRATE command. Only once every key in a slot has been successfully migrated is the slot finally assigned to the target node, and the cluster configuration is propagated to all other nodes via gossip.
# Interactive reshard: move 500 slots to a specific target node
redis-cli --cluster reshard 10.0.2.10:7000
# Non-interactive reshard for scripting and automation
redis-cli --cluster reshard 10.0.2.10:7000 \
--cluster-from abc123def456 \
--cluster-to 789ghi012jkl \
--cluster-slots 500 \
--cluster-yes
# Move slots from multiple source nodes at once with "all"
redis-cli --cluster reshard 10.0.2.10:7000 \
--cluster-to 789ghi012jkl \
--cluster-slots 500 \
--cluster-from all \
--cluster-yes
An often overlooked parameter is --cluster-timeout, which controls the timeout for the internal MIGRATE operation per key. For keys with very large values, such as extensive hashes or sorted sets, the default value can be too tight, leading to aborted migrations of individual keys. For clusters with known large individual values, this timeout should be deliberately increased before starting a resharding operation.
3. Slot migration step by step: MIGRATING and IMPORTING
At the heart of every slot migration in Redis Cluster are two temporary states a slot takes on across the involved nodes during migration. The source node marks the slot as MIGRATING, meaning that node keeps serving requests for keys already present in that slot, but responds with an ASK redirect to the target node for requests concerning keys it no longer owns. The target node simultaneously marks the same slot as IMPORTING, but only accepts requests preceded by an ASKING command.
This dual marking is the mechanism that prevents downtime during migration: a client requesting a key that has already been migrated receives an ASK redirect from the source node, follows it to the target node, and gets the correct answer there. Only once every key in a slot has been successfully moved is the migration finalized on both nodes via CLUSTER SETSLOT <slot> NODE <target-id>, the MIGRATING and IMPORTING state is cleared, and from that point on the slot unambiguously belongs to the target node.
# Manual low-level slot migration (what --cluster reshard automates)
# 1. Mark the slot as MIGRATING on the source node
redis-cli -p 7000 cluster setslot 12539 migrating 789ghi012jkl
# 2. Mark the same slot as IMPORTING on the target node
redis-cli -p 7003 cluster setslot 12539 importing abc123def456
# 3. Migrate every key in the slot individually
redis-cli -p 7000 cluster getkeysinslot 12539 100
redis-cli -p 7000 migrate 10.0.2.13 7003 "" 0 5000 keys \
"order:9912" "order:9913" "order:9914"
# 4. Once all keys are moved, finalize slot ownership on both sides
redis-cli -p 7000 cluster setslot 12539 node 789ghi012jkl
redis-cli -p 7003 cluster setslot 12539 node 789ghi012jkl
A critical point with manual slot migration: the final CLUSTER SETSLOT ... NODE assignment must be applied consistently across all affected nodes, not just source and target, otherwise conflicting views of slot ownership arise across the cluster. For that reason, production environments should almost always use redis-cli --cluster reshard instead of manual individual steps, since the tool automatically ensures this consistency.
4. Safely adding nodes
Adding a new node to a running Redis Cluster happens in two separate steps: first the new node is joined via redis-cli --cluster add-node as an empty cluster member with no assigned slots, then a separate resharding step follows that actually assigns it slots and therefore data. This separation is deliberate: it allows verifying that the new node is a fully functional cluster member before production data is migrated onto it.
When adding a replica node instead of a master, the master it should be attached to is specified additionally, via the --cluster-slave parameter together with --cluster-master-id. Without an explicit value, Redis Cluster automatically picks the master with the fewest existing replicas, which makes sense in most cases but should be explicitly overridden for deliberate capacity planning.
# Step 1: join a new empty master node to the running cluster
redis-cli --cluster add-node 10.0.2.16:7006 10.0.2.10:7000
# Step 1b: join a new replica node, attached to a specific master
redis-cli --cluster add-node 10.0.2.17:7007 10.0.2.10:7000 \
--cluster-slave \
--cluster-master-id abc123def456
# Step 2: verify the new node joined with zero slots assigned
redis-cli -c -p 7006 cluster nodes | grep myself
# Step 3: reshard slots onto the new master to give it real capacity
redis-cli --cluster reshard 10.0.2.10:7000 \
--cluster-to <new-node-id> \
--cluster-slots 2730 \
--cluster-from all \
--cluster-yes
A common mistake is loading the new node with a large share of slots right away instead of proceeding gradually. Migrating in stages, for example several batches of just a few hundred slots spread over several hours, lets you observe the impact on the new node's CPU and network load and stop early if problems appear, before the entire planned slot share has been migrated.
5. Safely removing nodes
Before a master node can be removed from a Redis Cluster, all of its slots must first be migrated to other nodes, a cluster refuses to remove a master that still has assigned slots. The sequence is therefore always: first distribute all slots of the node being decommissioned onto remaining nodes via --cluster reshard, and only then use redis-cli --cluster del-node to actually remove it from the cluster.
Removing a replica node skips the reshard step entirely, since replicas own no slots of their own, they can be removed directly via del-node. The only important thing here is to make sure the associated master still has enough remaining replicas for failover safety before a replica is permanently removed from the cluster.
# Step 1: move all slots away from the node being decommissioned
redis-cli --cluster reshard 10.0.2.10:7000 \
--cluster-from <node-to-remove-id> \
--cluster-to <remaining-node-id> \
--cluster-slots 5461 \
--cluster-yes
# Step 2: verify the node now owns zero slots
redis-cli -c -p 7002 cluster nodes | grep <node-to-remove-id>
# Step 3: remove the now-empty node from the cluster
redis-cli --cluster del-node 10.0.2.10:7000 <node-to-remove-id>
# Removing a replica is simpler: no slots to migrate first
redis-cli --cluster del-node 10.0.2.10:7000 <replica-node-id>
A safety net that has proven itself in practice: before the final del-node, run redis-cli --cluster check against the cluster to confirm that cluster_state:ok holds and all 16384 slots remain correctly assigned. Only after that confirmation should the node being removed actually be shut down, not before.
6. Automated resharding and rebalancing
Alongside targeted --cluster reshard, redis-cli --cluster rebalance offers an automated alternative that recalculates and evens out the slot distribution across all master nodes, without having to manually specify source and target for every single slot block. The tool optionally accounts for different capacity weights per node via --cluster-weight, which is relevant with heterogeneous hardware in the cluster.
The --cluster-use-empty-masters parameter is particularly useful when adding several new nodes at once, since rebalance by default excludes masters with no slots at all from automatic distribution, as a safety measure to prevent accidentally redistributing onto nodes that are not yet fully set up. Anyone who deliberately wants to include new, empty masters in the distribution must set this flag explicitly.
# Automatic rebalance including newly added empty master nodes
redis-cli --cluster rebalance 10.0.2.10:7000 \
--cluster-use-empty-masters
# Rebalance with a maximum threshold to avoid over-correcting
# (only rebalance nodes deviating more than 5% from the target)
redis-cli --cluster rebalance 10.0.2.10:7000 \
--cluster-threshold 5
# Always simulate first to review the planned moves
redis-cli --cluster rebalance 10.0.2.10:7000 \
--cluster-simulate \
--cluster-use-empty-masters
The --cluster-threshold parameter prevents unnecessary resharding when the distribution is already close to balanced: only nodes whose slot share deviates from the ideal target by more than the given percentage get rebalanced at all. That considerably reduces the number of unneeded slot migrations and is especially noticeable in large clusters with many nodes, where a full redistribution without a threshold would generate a disproportionate amount of traffic.
7. Recognizing and avoiding downtime risks
Although resharding in Redis Cluster is fundamentally designed to work without downtime, there are real risks that can lead to noticeable delays or, in extreme cases, brief unavailability. The biggest risk is very large individual keys: the MIGRATE operation blocks the source node for the duration of transferring a single key, and for a hash or sorted set spanning several hundred megabytes, that can create noticeable latency for every other client querying the same node in the meantime.
A second risk concerns network bandwidth between the involved nodes during large scale resharding operations. If too much slot migration is started at once, for example all slots of a node being decommissioned in a single large batch, it can considerably reduce the bandwidth available for normal application traffic between nodes. The solution is to perform resharding in smaller batches with pauses in between, instead of migrating everything in a single pass.
# Reshard in smaller batches with pauses to limit impact
for i in $(seq 1 10); do
redis-cli --cluster reshard 10.0.2.10:7000 \
--cluster-from <node-to-remove-id> \
--cluster-to <target-node-id> \
--cluster-slots 500 \
--cluster-yes
sleep 30 # let the cluster settle before the next batch
done
# Identify unusually large keys before resharding a node
redis-cli -p 7000 --bigkeys
# Increase the per-key migrate timeout for known large values
redis-cli --cluster reshard 10.0.2.10:7000 \
--cluster-timeout 15000 \
--cluster-slots 500 --cluster-yes
For clusters with known large individual values, it is also advisable to identify these keys beforehand and migrate them individually and deliberately, instead of encountering them unexpectedly during the automated batch process of --cluster reshard. redis-cli --bigkeys provides a quick overview of unusually large keys in the dataset before a resharding operation is even started.
Mironsoft
Redis Cluster operations, resharding, and capacity planning
Resharding is coming up and nobody wants to touch it?
We plan and guide your Redis Cluster resharding, from batch size and timeout configuration to monitoring during the migration, so production data moves safely and without downtime.
Resharding planning
Tailoring batch size, timeouts, and sequencing to your data profile
Node migration
Safely onboarding new nodes, controlled removal of old ones
Live support
Monitoring and rollback readiness throughout the entire operation
8. Monitoring during a resharding operation
During an ongoing resharding operation, several metrics should be watched in parallel to catch problems early instead of noticing them only after the migration is complete. CLUSTER INFO continuously shows the overall state of the cluster, CLUSTER NODES shows the current slot assignment per node, and the latency statistics from INFO commandstats show whether the MIGRATE operations are having a noticeable impact on the cluster's general response time.
| Metric | Command | What to watch for |
|---|---|---|
| Cluster state | cluster info |
cluster_state must stay ok throughout |
| Slot consistency | --cluster check |
No open MIGRATING/IMPORTING after completion |
| Latency spikes | latency history |
Outliers during MIGRATE calls |
| Memory usage | info memory |
Don't fill the target node past maxmemory |
A particularly useful command during ongoing migrations is redis-cli --cluster check <any-node>, which explicitly checks whether any slots are still stuck in a MIGRATING or IMPORTING transitional state, for example because a resharding operation got interrupted. Such stuck states should not be ignored, they can lead to inconsistent client behavior if older client libraries do not handle ASK redirects correctly.
9. Rollback strategies for a failed resharding operation
If a resharding operation aborts unexpectedly, for example due to a network error or a crashed node during migration, the affected slots remain stuck in the MIGRATING or IMPORTING state. In that state, the cluster keeps functioning normally for most access thanks to the ASK redirect logic, but the state should be resolved as soon as reasonably possible to avoid further inconsistencies.
The safest rollback strategy is to simply continue the interrupted migration rather than undo it: since every key is migrated individually, already transferred keys are already safely on the target node, and running redis-cli --cluster fix again detects stuck slots and automatically completes migration of the remaining keys, instead of pushing already migrated data back.
# Detect and automatically resolve stuck slot migrations
redis-cli --cluster fix 10.0.2.10:7000
# Manual inspection before running fix, to understand the scope
redis-cli -c -p 7000 cluster nodes | grep -E "migrating|importing"
# If a node is unreachable and blocking the fix, verify its
# last known state before forcing slot ownership decisions
redis-cli -c -p 7003 cluster info | grep cluster_state
# After fix completes, always re-verify full slot coverage
redis-cli --cluster check 10.0.2.10:7000
A true rollback to the state before the migration is not architecturally supported in Redis Cluster and should not be attempted, since it increases the risk of data inconsistency rather than reducing it. The more robust strategy is always to repair forward, using --cluster fix, instead of rolling backward, combined with a full backup of the entire dataset before starting a larger resharding effort as a final safety net.
10. Summary
Cluster resharding without downtime is not a special case in Redis Cluster but a firmly built in, recurring operational task that stays available through the MIGRATING/IMPORTING state of individual slots and the ASK redirect logic while data is still in motion. redis-cli --cluster reshard automates this for targeted moves, --cluster rebalance for automatic redistribution, both build on the same underlying mechanisms.
The most important practical rules are: perform resharding in small batches rather than one large batch, identify large individual keys beforehand and account for their timeout requirements, continuously monitor with cluster info and --cluster check, and always repair forward with --cluster fix rather than rolling back after an interrupted operation. Following these rules lets Redis Cluster grow and shrink over years without ever needing a maintenance window for the data redistribution itself.
Cluster Resharding Without Downtime: The Essentials at a Glance
MIGRATING/IMPORTING preserves availability
ASK redirects keep slots reachable for clients throughout the migration.
Migrate in batches
Small batches with pauses instead of one large resharding operation.
Identify large keys upfront
Use redis-cli --bigkeys, raise the timeout for known large values.
Repair forward, don't roll back
--cluster fix for stuck migrations instead of a manual rollback.