Open Source · Apache-2.0Linux / macOS / Windows No telemetry · No paid tier

Sparse files & VM images

A sparse file lies about its size: a raw VM disk can report 500 GB while only 20 GB of it is real data — the rest is holes the filesystem never allocated. Tools that read files byte-by-byte (scp, SFTP, naive scripts) expand every hole into actual zeros: the copy takes hours, and the destination file balloons to the full logical size.

fast-copy asks the filesystem where the data actually is, using SEEK_DATA / SEEK_HOLE, and copies only the allocated extents — recreating the holes on the destination instead of writing zeros. The pre-flight space check uses allocated size too, so a 900 GB destination correctly accepts a “2.3 TB” job. This is what makes Longhorn replica backups, libvirt/qcow2 image trees and database preallocations practical to copy at all.

Real numbers

Sparse VM backup · 346 sparse files (Longhorn replicas)
2.3 TBLogical size
12.2 GBOn disk
2.2 TBHoles skipped
∞×vs naive cp

SEEK_DATA / SEEK_HOLE walked data-extents only. Pre-flight space check used allocated count, so a 900 GB destination accepted the job.

Examples

Back up a libvirt image directory

fast-copy /var/lib/libvirt/images /mnt/backup/images

Sparse handling is automatic — there is no flag to remember. Raw, qcow2 and preallocated images all copy at their allocated size, and every file is hash-verified after the copy as usual.

Longhorn replicas (need root)

fast-copy --use-sudo /var/lib/longhorn/replicas/pvc-* /mnt/backup_pvc/

Combine with --use-sudo for paths only root can read — see the sudo backups guide for the audit-log details.

Preview how much will really be copied

fast-copy /var/lib/libvirt/images /mnt/backup/images --dry-run

The plan reports allocated bytes — what will actually move — not the logical file sizes.

Full measurement methodology for the numbers above is on the benchmarks page.