Comparison

Backup Data vs rsync: a transfer tool is not a backup system

rsync is the best file-copying tool ever written and it has no versioning, no retention, and no restore verification. An honest comparison, including when rsync is still the right answer.

6 min readBackup Data

rsync is one of the most useful programs ever written. It is on every machine you will ever touch, it moves files over SSH with a delta algorithm that was clever in 1996 and is still clever now, and for copying data from A to B it has no real competition.

It is also, on its own, not a backup system — and the gap is not about features anyone forgot to add. rsync synchronises directories. Backup is a different job that happens to involve copying files, in the same way that accounting is a different job that happens to involve arithmetic.

This is an honest comparison, including the cases where rsync is still what you should use.

The script almost everyone writes

rsync -av --delete /var/www/ backup-server:/backups/www/

This is a good command. It is also, as a backup strategy, one deletion away from useless — and the reason is --delete.

Without --delete, your backup grows forever and never reflects deletions. Files removed from production three years ago are still there, you are paying to store them, and you can never answer "what did this directory look like in March?"

With --delete, deletions propagate. Someone runs rm -rf on production at 4pm, the sync runs at 2am, and the backup faithfully deletes the same files. You now have two identical copies of the disaster.

That is the trap, and it is inherent: rsync's job is to make the destination match the source. When the source is wrong, a correct rsync makes the destination wrong too. Backup systems are built on the opposite premise — that the source might be wrong, and history is what saves you.

Experienced rsync users will point out you can build versioning with hard links:

rsync -av --delete \
  --link-dest=/backups/www/2026-08-20 \
  /var/www/ /backups/www/2026-08-21/

Unchanged files become hard links to yesterday's copy, so each dated directory looks like a full backup while only consuming space for what changed. This is genuinely clever, it is what rsnapshot and Time Machine are built on, and it works.

It also has real limits worth knowing before you build on it:

  • Deduplication is whole-file only. Change one byte in a 4 GB database dump and you store 4 GB again. Content-defined chunking stores the changed region.
  • Hard links need one filesystem. Your snapshots and your live backup are on the same volume, which is one disk failure away from all of them.
  • No integrity verification. Nothing detects bit rot; a corrupted file is silently linked forward into every future snapshot.
  • Retention is your problem. You write the script that deletes old directories, and you get to be the one who gets the date arithmetic wrong.
  • No encryption at rest. rsync encrypts in transit over SSH. On the destination disk, everything is plaintext.

So: --link-dest gets you versioning. It does not get you a backup system, and the difference is mostly in the things that only matter on the day you need them.

Side by side

rsyncBackup Data
Versioned historyManual, via --link-destEvery run is a snapshot
DeduplicationWhole fileContent-defined chunks (FastCDC)
Encryption at restNone — you add LUKS or nothingAES-256-GCM, client-side
Integrity on restoreNoneChecksums verified before reassembly
Retention policyA script you writepruneSnapshots, with dry-run
Deletion protection--delete propagates deletionsSnapshots are immutable
DestinationA box you own and maintainManaged
CostFree + your server + your timeFree to 5 GB, then from $12/mo
Restorersync the other wayclient.restore(...)
Works offline / air-gappedYesNo, needs network
Available everywhereYes, universallyNode or Go SDK

What rsync is genuinely better at

This is not a list of consolation prizes. There are jobs where rsync is the correct tool and reaching for anything else is overengineering.

One-off migrations. Moving 200 GB between two servers you control. rsync, resumable, done.

Keeping a live mirror in sync. A read replica of a static asset directory, updated every five minutes for serving rather than for recovery.

Air-gapped or offline destinations. rsync to a USB drive or a machine on an isolated network works with no service dependency at all.

Environments where you cannot install anything. rsync is already there. On a locked-down host, that matters more than any feature comparison.

Feeding another backup system. These are not mutually exclusive, and the combination is often right — rsync to stage files locally, then snapshot the staging directory. Our S3 guide uses exactly this shape with aws s3 sync.

What the difference looks like in practice

The scenario that separates them is not exotic. It is the ordinary one.

A bad migration corrupts a table on Tuesday. Nobody notices until Friday.

With rsync mirroring nightly: the corruption was faithfully copied Tuesday night, and again Wednesday, Thursday, and Friday. Your backup is a perfect copy of the broken data. Unless you built --link-dest snapshots and kept more than three days of them, there is nothing to go back to.

With versioned snapshots: Monday's snapshot is untouched and immutable. You restore it into a scratch database, confirm the table is intact, and pull the rows forward.

That is the entire argument. Not speed, not compression, not cost — the ability to go back to before the problem started, which requires history that the current state cannot overwrite.

If you are moving from rsync

The migration is smaller than expected, because your existing script already produces the hard part: a directory that reflects current state.

# Keep whatever you already do to assemble the data.
rsync -av --delete /var/www/ ./staging/www/
pg_dump --format=custom --file=./staging/db/app.dump app_db
import { BackupClient } from "@lighthouse-web3/baas-js-sdk";

const client = new BackupClient({
  apiKey: process.env.LH_API_KEY,
  workspaceId: process.env.LH_WORKSPACE_ID,
});

const snapshot = await client.backup(["./staging"], {
  description: "nightly",
  tags: { type: "files", host: "web-01" },
  encryption: {
    keyfilePath: "/secure/lh.keyfile",
    passphrase: process.env.LH_KEYFILE_PASSPHRASE,
  },
});

Note that --delete is now the right choice on the staging mirror, where it was dangerous before. Each upload is an immutable point-in-time snapshot, so history lives in the snapshots rather than in an ever-growing local directory. The mirror should track the source exactly.

You hold the encryption keys — lose the keyfile and passphrase and the data is unrecoverable, with no server-side reset.

The honest summary

If you need to copy files from one place to another, use rsync. It is excellent, it is free, and nothing here replaces it.

If you need to answer "what did this look like last Monday, and can I prove it restores" — that is a different question, and rsync was never built to answer it. The --link-dest pattern gets you partway and stops short of encryption, integrity verification, chunk-level dedupe, and a destination you do not have to maintain.

Plenty of good setups use both: rsync to gather, snapshots to keep.

Start with the free tier: backupdata.io has 5 GB free, no card, and the 10-minute quickstart gets you to a first verified snapshot today.

Start with the free tier

5 GB free, no card required. Point your existing dump at Backup Data and get to a first verified snapshot in about ten minutes.

Read the quickstart

Keep reading

Comparison · 7 minBackup Data vs AWS Backup: which fits your stack?Comparison · 8 minBackup Data vs Backblaze B2: a backup system or a cheap bucket?Comparison · 7 minBackup Data vs BorgBackup: who runs the repository?