← All guides

2026-06-10

Syncing and Pushing VMs with heyvm

Syncing and Pushing VMs

heyvm gives you three ways to move a sandbox's disk around: sync for machine-to-machine transfers, archives for persisting mount contents to the cloud, and snapshots for turning a disk into a reusable image. This guide covers each in turn.

Syncing discs between two machines

heyvm sync packages a full VM (rootfs, config, and mounts) and transfers it peer-to-peer over iroh. No cloud intermediary is involved — the two machines connect directly.

On the sending machine

Package a sandbox and serve it. heyvm prints a heyo:// ticket and waits for a receiver to connect:

heyvm sync push my-sandbox

Useful flags:

  • --include-memory — include the memory snapshot so the receiver resumes a running VM (Firecracker only; falls back to disk-only on a kernel mismatch).
  • --no-mounts — ship only the rootfs and config, dropping mount disk images.

On the receiving machine

Hand the ticket to sync pull to restore it as a new local sandbox:

heyvm sync pull heyo://ticket123...

Useful flags:

  • --name <name> — name for the restored sandbox (defaults to the source name).
  • --backend <backend> — target backend, e.g. firecracker or kvm (defaults to the source's backend).
  • --no-start — restore without starting the sandbox.

Checking transfers

heyvm sync list --limit 20

Tip: to move a persistent host-directory volume on its own rather than a whole sandbox, use heyvm volume push <name> / heyvm volume pull <source>.

Archives

An archive persists a sandbox's mount contents (not the whole VM) to the Heyo server, where it lives independently of any sandbox. Archives are how you redeploy code and data without cloning an entire VM.

Archive a running sandbox's mounts:

heyvm archive my-sandbox --name my-archive

You can also archive an arbitrary local directory with no sandbox involved:

heyvm archive-dir ./my-project --name my-project-v1

By default build assets like node_modules, target, and dist are ignored — pass --no-ignore to capture everything.

Manage existing archives:

heyvm list-archives
heyvm delete-archive ar-a1b2c3d4

To push an archive's contents onto a deployed sandbox:

heyvm update my-sandbox --archive ar-a1b2c3d4

Authentication uses a JWT passed via --token or the HEYO_ARCHIVE_TOKEN environment variable.

Snapshots

A snapshot flattens a sandbox's current disk state into a reusable local image. Where sync moves a VM between machines and archives store mount contents in the cloud, a snapshot becomes a template you can spin new sandboxes from.

heyvm snapshot my-sandbox --name my-snapshot-v1

By default the sandbox restarts after snapshotting; pass --no-restart to leave it stopped. Images land under ~/.heyo/images/ (the exact path and format depend on the backend — qcow2 for libvirt, ext4 rootfs for Firecracker, a committed image for Docker).

Publishing a snapshot

To make a snapshot available beyond your machine, publish it to the image registry:

heyvm images publish my-sandbox \
  --name "my-custom-image" \
  --description "Ubuntu with Node.js 20" \
  --private
  • --private publishes an immediately-deployable image scoped to your account. Omit it to submit to the public registry (subject to review).
  • --sysprep strips machine-id, SSH host keys, and logs before upload (libvirt only).

At a glance

Command Moves Destination
heyvm sync push / pull Full VM (rootfs + config + mounts) Another machine (P2P)
heyvm archive / archive-dir Mount / directory contents Heyo cloud
heyvm snapshot Disk state Reusable local image
heyvm images publish Snapshot Image registry