The problem
Every VPS provider who wants to switch panels hits the same wall: customers. A VM recreated from scratch gets a new IP, a new MAC, sometimes a disk to copy by hand. That means DNS updates, MAC-bound licences to redo, night-time maintenance windows and tickets.
KoaVM starts from a simple idea: you don't recreate the VM, you move it. Same disk, same IP, same MAC, with as little downtime as possible.
The steps, one by one
1. Reading the source. The panel logs into the source node over SSH with its key and reads the VM definition (the libvirt domain for SolusVM 2 and libvirt, the VM config for Proxmox): disks, format (qcow2, raw, LVM), bus, firmware (BIOS or UEFI), MAC and IP. With the old panel's API it adds hostname and customer.
2. Checks. Before touching anything it verifies space on the target pool, that the node is reachable, that the IP can reach the new node and that the MAC isn't used by another instance. If a check fails, the VM doesn't start.
3. Mirror copy while the VM runs. KoaVM prepares an empty VM on the KoaVM node with disks of the same size and exposes them with qemu-nbd through an SSH tunnel. Then, on the source node, it starts a mirror copy to those disks: with libvirt (SolusVM 2 included) it's virsh blockcopy, with Proxmox it's drive-mirror over QMP (with a job-id, because on Proxmox 9 the old HMP monitor command no longer works). Blocks flow to the new node while the VM keeps working, and every new write is also applied to the copy.
4. The switch. When the copy is in sync, the source VM shuts down, the copy is closed, KoaVM pins the network interface name and boots the VM on KoaVM with the same MAC and the same IP. That's the downtime the customer sees: in our tests between 8.8 and 15.8 seconds, on nested lab nodes.
5. Clean-up. With the old panel's API the source VM is suspended there, so nobody starts it by mistake. If the IP belongs to a provider (OVHcloud, Hetzner), KoaVM has already moved it to the new node's server.
6. If anything goes wrong at any point, the panel stops everything, starts the source VM again as it was and, if it had moved the provider IP, moves it back.
How we know nothing is lost
Every lab VM runs a small program that writes a counter to disk every 0.2 seconds, with fsync. After the move the counter must be continuous: a missing number would mean a lost write. In every test it stayed continuous, and secondary disks had the same checksum as the source.
| VM | From | Downtime | HTTP probe |
|---|---|---|---|
| vps-a | KVM/libvirt | 8.8 s | 9.2 s |
| pve-web3 | Proxmox VE, LVM | 13.2 s | 10.7 s |
| pve-web1 | Proxmox VE, 2 disks | 13.8 s | 10.4 s |
| solus-web1 | SolusVM 2 | 15.8 s | 14.9 s |
The «HTTP probe» is how long the VM's website didn't answer, measured from outside.
When it can't be done live
Some VMs are better moved cold: Windows, VMs with very large disks and little free capacity, or when you prefer a maintenance window. The VM shuts down, the disk is copied, the VM starts on KoaVM: downtime equals the copy (28 to 45 seconds for 8–10 GB disks in our tests). You can schedule it at a set time, and customers get an email before and after.
Try it
The KoaVM free trial includes 1 node and 5 VPSs, migration included. Start from the migration guide and join the waitlist.