rsync copies files — but only the differences. On a repeat run it sends just the changed blocks, which turns a multi-gigabyte backup into a few megabytes over the wire. That single property made rsync the backbone of two decades of backups, mirrors, and deploys.

The daily form #

Sync a directory to another location
$ rsync -av projects/ backup/projects/

-a is archive mode — recursion plus permissions, times, symlinks, the lot. -v narrates. Note the trailing slash on the source: projects/ copies the contents; projects copies the directory itself. The slash rule is the number-one rsync surprise, and it is the same ambiguity as cp — here it is load-bearing.

The flags that matter #

FlagEffect
-aArchive: recurse and preserve attributes
-v / -vvVerbose / more verbose
-nDry run — show what would happen
--deleteRemove destination files missing from source
-zCompress during transfer
--exclude=Skip patterns
-PProgress plus resumable partial files

Dry-run before any real sync is the habit; --delete is the flag that makes it non-negotiable, because delete makes the sync two-directional in consequence if not in intent.

Real patterns #

A nightly backup with exclusions, over ssh:

Back up a laptop to a server, skipping churn
$ rsync -avP --delete --exclude=".cache" --exclude="node_modules" ~/projects/ backup@server:/backups/laptop/

A deploy: build locally, ship only the delta, then flip a symlink:

Atomic-ish deploy by rsync + symlink
$ rsync -av --delete dist/ server:/srv/app/releases/v1.5/
$ ssh server 'ln -sfn /srv/app/releases/v1.5 /srv/app/current'

Restore is the same command with source and destination swapped — backups you have never restored are hopes, not backups.

For encrypted, deduplicated backups beyond mirroring, see restic and friends; for imaging whole disks, dd. The terminal notes series continues.