Moving a running virtual machine from one physical host to another without shutting it down is the capability that turns a collection of servers into a manageable pool: hardware maintenance happens without maintenance windows, load rebalances without anyone noticing, and a failing host evacuates its guests before it fails. KVM's live migration, driven through one virsh command, moves a machine's memory and execution state across the wire while the guest keeps running, with a total pause measured in a blink. The capability has prerequisites that are architecture rather than options, and this article covers both: the storage and network designs that make migration possible, the command and its modes, the convergence tuning that separates a clean migration from a stubborn one, the compressed and post-copy variants, and the operational procedure that turns the whole thing into a runbook step rather than a hero event.
What live migration moves and what it leaves
A running VM is two things: its execution state, CPU registers, memory pages, device states, held by the host process, and its storage, the disk blocks that hold the filesystem. Live migration moves the first across the network in real time and requires the second to already be reachable from both hosts, which is why the storage design is the first section of this article and not an afterthought. The guest's memory is copied iteratively, the first pass copies everything, subsequent passes copy only the pages the guest dirtied during the previous pass, and the loop continues until the remaining delta is small enough to copy inside one short pause, when the guest stops on the source, the final pages transfer, and execution resumes on the destination.
That final pause is the migration's public face: the guest's network connections survive it, its applications feel a stall measured in tens to hundreds of milliseconds, and TCP sessions retransmit through the gap exactly as they do through any momentary congestion. What live migration is not: it is not high availability, the failure of the source host mid-migration aborts the process and the guest continues on the source, untouched, and it is not a backup, the disk stays where it always was. It is planned mobility for healthy machines, and the evacuation scenario for a degrading host is a race between judgment and hardware, covered in the procedure section.
The storage prerequisite, shared or block-copied
The classic migration architecture puts every guest disk on storage visible to all hosts in the pool, and the candidates for that shared layer are the well-known families. NFS exports from a capable filer carry the simplicity prize, one mount per host, the image files ordinary paths, and the performance adequate for the general tier. iSCSI and Fibre Channel provide block storage with the multipathing discipline the LVM article covered, and the guests' disks are logical volumes every host can see. Ceph RBD and GlusterFS provide the distributed-storage answer with native libvirt integration, the <disk type='network'> declaration pointing at the pool rather than a file path, and the cluster storage world in general turns the shared-storage prerequisite into an installed capability rather than a project.
The alternative to shared storage is migrating the disk along with the memory, the block-migration mode, invoked through the --copy-storage-all flag, which streams the disk image across the wire during the same iterative loop. The mode costs the migration duration a factor proportional to disk size and write rate, tens of gigabytes stream in minutes on a fast link, and it suits the scenarios where a shared layer does not exist, the single-machine evacuation to a spare, the consolidation project moving guests onto the new cluster one at a time. The two modes compose the decision: shared storage is the architecture for a pool that migrates routinely, block copy is the tool for the migrations that happen between islands.
The network between hosts
Migration traffic is a memory image moving across a TCP connection, and the network it travels on deserves its own design rather than borrowing the guest bridge. The standard pattern is a dedicated migration network, a second physical interface per host, its own addresses, carrying nothing but libvirt's migration streams and the management traffic that keeps the hosts honest. The libvirt remote protocol that orchestrates the move, qemu+ssh:// in the canonical form, authenticates through SSH between hosts, the same bastion-pattern key discipline from earlier in this series, and the migration data stream itself can be directed onto the dedicated interface through the migration URI parameter:
virsh migrate --live app01 qemu+ssh://host2/system --migrateuri tcp://10.0.99.2
On a 10-gigabit dedicated link, a 32-gigabyte guest's first pass copies in under a minute, and on a shared 1-gigabit link, the same guest takes the better part of an hour, the arithmetic that explains why the migration network is not an optional nicety on any host expected to migrate routinely.
The command and the modes that matter
The canonical invocation is one line:
virsh migrate --live --persistent --undefinesource app01 qemu+ssh://host2/system
reading: live-migrate the machine, register it in the destination's persistent configuration, remove it from the source's, so the machine ends up defined on host2 and undefined on host1, the state a fleet expects after a deliberate move. Dropping the two persistence flags gives the opposite, the machine remains defined on both hosts, useful for a temporary evacuation with a planned return.
Monitoring the process belongs to a second terminal:
virsh domjobinfo app01
which prints the elapsed time, the bytes remaining, and the all-important data-total against data-remaining, the progress bar that tells you whether the loop is converging, the delta shrinking each pass, or stuck, which is the next section's topic. Abort is always available and always safe, virsh domjobabort app01, stopping the process and leaving the guest running on the source exactly as it was.
Convergence tuning, when the guest out-dirties the copy
A guest with a heavy write workload, an active database, a build machine, anything that dirties memory faster than the link copies it, can keep the migration loop from ever shrinking the delta, the migration that runs forever. KVM has two named mechanisms for exactly this trap. Auto-converge, --auto-converge, throttles the guest's CPU progressively as the loop stalls, slowing the dirtying rate until the copy catches up, the guest's applications see a gradual slowdown that buys the convergence, and the tradeoff is honest: throughput during the migration dips so the migration can finish.
Compression, --compressed with the xbzrle algorithm, compresses the memory pages in flight, the delta pages especially, and a compressible workload, and most are, sees its transfer shrink by half or better, which shortens the loop and reduces the convergence pressure. The two compose, and the stubborn guest gets both:
virsh migrate --live --auto-converge --compressed app01 qemu+ssh://host2/system
The third mechanism, post-copy, changes the fundamental contract, --postcopy switches the order, the guest moves to the destination immediately, and the memory pages follow on demand, page-faulting them across the wire. The pause disappears entirely, the trade is the failure window: if the network breaks during post-copy, the guest stalls hard, and if the source host dies, the guest is lost. The mode is the right answer for the specific case, the guest too hot for pre-copy convergence where a brief slowdown is preferable to an infinite loop, and it belongs behind a deliberate runbook decision rather than as a default, because its failure mode is the one this article's safety design everywhere else avoids.
The operational procedure and the evacuation race
The routine migration follows a short procedure that keeps the risks visible. Confirm the destination can see the storage, the shared mount or the pool reachable from host2. Confirm the CPU compatibility, same vendor and a compatible model definition, and the host-passthrough configuration from the virtio article carries the strictest constraint: a passthrough guest migrates cleanly only between identical CPU models. Run the command with the monitoring terminal open, watch the delta shrink across the domjobinfo readings, and after completion verify on the destination, virsh list on host2 showing the machine, the application answering inside it.
The evacuation of a degrading host is the same procedure with a decision clock, and the honest version of the runbook names the thresholds: if the host shows early degradation, storage errors, memory pressure, thermal events, migrate the guests while everything still works, because migration from a healthy host is boring and migration from a dying one is a race. The judgment rule that experienced operators keep: evacuate on the first hint, the audience for heroism is smaller than the audience for uptime. And for the host that dies outright, live migration is explicitly not the answer, the failed-guest path through the shared storage and a fresh start on a surviving host is the design that shared storage bought in the first place.
The closing checklist
Shared storage visible to all hosts, or block-copy mode chosen deliberately. A dedicated migration network on any pool that migrates routinely. SSH-keyed libvirt connectivity between hosts, the bastion discipline applied to the management path. The command with persistence flags for permanent moves, without for temporary ones. Auto-converge and compression for the hot guests, post-copy behind a runbook decision with its failure mode written down. The domjobinfo monitoring as a habit and domjobabort as the always-available retreat. The evacuation thresholds agreed in daylight rather than negotiated at night. A pool built this way has the property that the hardware below it became furniture, replaceable without ceremony, which is the entire promise of the virtualization layer kept.
## Testing the path before the night needs it
A migration setup that has never been exercised is a hypothesis, and the test procedure is short enough to belong to the first week of any new pool. The rehearsal uses a disposable guest, a small machine with a known workload, a continuous ping from a third host, and one migration watched from two terminals. The domjobinfo readings confirm the convergence shape, the delta shrinking pass by pass, the completion time recorded as the pool's baseline. The ping stream across the migration measures the guest-visible pause, the gap of tens or hundreds of milliseconds that the applications will feel, and the ARP update as the destination announces the guest's address is visible as the point where the traffic shifts.
Inside the guest, the application-level check completes the picture: a database guest runs a count query across the migration, a web guest serves requests, and the result confirms that the moved machine is functionally identical to the one that started. The rehearsal's value compounds over the pool's life, because the recorded numbers turn the real event from a suspense story into a comparison, this migration is taking twice the baseline, the network is degraded, a fact visible in minutes rather than discovered through the failure of a three-hour migration at 2 a.m.
The migrate-to-file alternative and its niche
Between the live-migration and the shutdown-and-copy worlds sits a third option that solves the snapshot-and-restore shape: migrating the machine's state to a file, which suspends the guest, writes its complete state to a checkpoint image, and allows resuming it later, on the same host or on any compatible one:
virsh migrate --p2f app01 /pool/checkpoints/app01.checkpoint --verbose
The pattern covers the scenarios where the network between hosts is not the bottleneck but the impossibility: the move to an offline destination through removable media, the long-term checkpoint of a machine that must pause for days and resume without state loss, and the debugging of a VM's behavior by capturing its exact running state for later replay. The file restore uses the symmetric --f2p mode, and the niche is narrow enough that its appearance in a runbook is always a specific, documented decision rather than a routine.
The one-paragraph perspective
Live migration is the capability that operationalizes the shared-storage investment, and the chain from this article composes with the whole series naturally: the migration network carries the virtio-speed memory streams, the guest agent from the previous article verifies the moved machine from the host, the cgroup budgets follow the machine through its definition, and the hardened management path carries the control traffic. The pool that puts these pieces together reaches the state where the physical hosts become interchangeable, and the administrator's question shifts from where is this machine to what is it doing, which is the question that actually matters.