reloca.toby XServer

reloca.to/Guides

Moving a server without downtime

A server can be copied while it serves its users, and stopped only for the last few seconds. Here is what that costs, what it needs, and how to tell in advance whether your server qualifies.

What the words mean here

Nobody moves a physical server without any interruption at all: the processes have to start again on the other machine, so there is a reboot. What can be removed is the hours of copying. The old server keeps working while its disks are read, and stops only for the last delta.

On a fast link that stop is under two seconds, measured on our bench with Debian 12 and Rocky 9. Add one reboot of the new server, and that is the whole interruption.

How it works

The tool puts one static binary on the old server, runs it as root and reads the block devices directly. At the same time it watches every write, so it knows which parts of the copy went stale: an eBPF program on the block layer where the kernel has it, ftrace where it does not, which reaches back to CentOS 7.

After the first pass only the changed blocks follow, pass after pass, each one smaller than the last. When the remaining delta would take a few seconds at the measured link rate, the filesystems are frozen with fsfreeze, the last delta crosses, and the new server comes up. Processes do not die during the freeze; their writes simply wait, and reads keep working.

What it needs

  • Root on the running server, over ssh. Nothing is installed there and nothing is written to its disks.
  • A kernel that can track writes: eBPF, or ftrace as far back as the 3.10 of CentOS 7.
  • A link faster than the server writes. This is the real condition, and it is measured, not guessed.

The command

There is no separate mode to turn on: the tool detects it from the fact that the old server answered from its own system rather than from a Live OS.

ssh -A root@NEW-SERVER
curl -fsSL reloca.to | bash
reloca.to -n root@OLD-IP      # the plan, nothing written
reloca.to root@OLD-IP

Ask for a shorter stop with -o converge=5: the agent then keeps re-sending deltas until the one still pending would take five seconds or less. Ask for more patience with -o patience=3600 if you would rather spend an hour of copying on a shorter freeze.

When it will not converge

If the server writes to disk faster than the link carries data away, the next delta is no smaller than the last one and waiting does not help. The agent measures both rates and says so instead of grinding:

the donor writes 20.4 MiB/s, the link carries 14.9 MiB/s (1.37x): the deltas
cannot shrink, this will not converge

Then it either takes the window it has, if that window is shorter than you allowed with -o max-est=, or refuses to freeze at all and leaves the old server untouched. Both outcomes are safe: the new server's disk is written, the old one never stopped, and the move can be repeated in the quiet hours.

What actually helps, in order: move at night, when the writing is less; use a faster link; or accept the off-line mode and an honest maintenance window.

The rehearsal you get for free

By default the old server is frozen twice. After the first freeze the tool takes a snapshot of the copy, thaws the donor, and runs the whole fix-up and verify on that snapshot while the old server serves its users again: the initramfs is built, grub is installed, the boot entry and the network are checked. Only then does it catch up and freeze for real.

This is what finds a target that would not boot while you still have both machines running. It costs one extra freeze window, which is about a second on a fast link and a minute or two on a slow one; -o precheck=0 skips it.

Measured, not promised

All of these numbers come from the same migration of a CentOS 7.9 server with a load generator writing about 20 MB/s, with the link shaped to real latency and loss.

LinkConvergenceFreeze windowWhole move
10 GbEon the third pass1.7 s223 s
400 Mbit, 20 mson the fourth pass8.7 s341 s
100 Mbit, 30 ms, 0.05% lossdoes not converge100 s953 s

The option that shapes each of these is in the option reference.

Try it on your own move

The tool is free, the dry run changes nothing, and the old server is only ever read.

curl -fsSL reloca.to | bash

All options