rsync: the Swiss Army knife of file sync
rsync copies files, but it only transfers the differences between source and destination. This makes it dramatically faster than copying everything again, especially over a network. It’s the backbone of most Linux backup scripts.
Basic usage
Copy a directory:
rsync -av /source/ /destination/
-a— archive mode (preserves permissions, timestamps, symlinks, etc.)-v— verbose output
The trailing slash matters:
rsync -av /source/ /destination/ # copies contents of source into destination
rsync -av /source /destination/ # copies source directory itself into destination
This is the #1 rsync gotcha. /source/ means “the contents of source.” /source means “the directory named source.”
Over a network
Sync to a remote server:
rsync -av /local/data/ user@remote:/backup/data/
Sync from a remote server:
rsync -av user@remote:/var/www/ /local/backup/www/
rsync uses SSH for transport by default, so it works wherever SSH works.
Common flags
rsync -avz /source/ /dest/ # compress during transfer
rsync -avP /source/ /dest/ # show progress + resume partial
rsync -av --delete /source/ /dest/ # delete files at dest not in source
rsync -avn /source/ /dest/ # dry run (show what would happen)
-P combines --progress and --partial (keeps partially transferred files so you can resume).
--delete makes the destination an exact mirror. Files at the destination that don’t exist at the source get deleted. Use this carefully.
Excluding files
Exclude patterns:
rsync -av --exclude='*.log' --exclude='.git' /source/ /dest/
Exclude from a file:
rsync -av --exclude-from='exclude.txt' /source/ /dest/
Where exclude.txt contains:
*.log
.git
node_modules
__pycache__
Incremental backups
rsync with --link-dest creates incremental backups that use hard links for unchanged files. This gives you full backups at each timestamp while using minimal disk space:
#!/bin/bash
BACKUP_DIR="/backup/$(date +%Y-%m-%d)"
LATEST="/backup/latest"
rsync -av --delete --link-dest="$LATEST" /data/ "$BACKUP_DIR/"
rm -f "$LATEST"
ln -s "$BACKUP_DIR" "$LATEST"
Each backup looks like a complete copy, but unchanged files are hard links to the previous backup. Delete any backup and the others remain intact.
Bandwidth limiting
Limit transfer speed to avoid saturating the network:
rsync -av --bwlimit=5000 /source/ user@remote:/dest/
This limits to 5000 KB/s. Useful when syncing during business hours.
Showing what would happen
Always dry-run first for destructive operations:
rsync -avn --delete /source/ /dest/
The -n flag shows what would be transferred and deleted without doing it.
Daemon mode
For frequent syncs to the same server, rsync daemon mode avoids SSH overhead:
On the server, configure /etc/rsyncd.conf:
[backup]
path = /backup
read only = no
auth users = backupuser
secrets file = /etc/rsyncd.secrets
Sync with:
rsync -av /data/ backupuser@server::backup/data/
Checking transfer status
rsync’s output shows what changed:
>f+++++++++— new file>f..t......— timestamp changed>f.st......— size and timestamp changed*deleting— file deleted at destination (with —delete)
Common mistakes
Trailing slash confusion. Double-check whether you want source/ or source. Test with -n first.
Using —delete without dry run. Always rsync -avn --delete first. A wrong source path with --delete can wipe out your backup.
Not using -a. Without it, rsync doesn’t preserve permissions, timestamps, or symlinks. -a is almost always what you want.
Syncing open databases. rsync copies files as-is. If a database has files open, the copy might be inconsistent. Dump the database first or use LVM snapshots.
Remarks
rsync is one of those tools that does one thing extremely well. The basic usage is simple enough to remember, and the flags are logical. For backups, for deploying code, for syncing directories — rsync is almost always the answer. The incremental backup trick with --link-dest alone is worth learning.
Related Posts
Vim survival guide for Linux admins
The minimum vim knowledge you need to survive on a Linux server. Editing config files without wanting to throw your keyboard.
Linux memory management: free, vmstat, and /proc
Understanding how Linux uses memory. Reading free correctly, using vmstat, and what /proc/meminfo actually tells you.
tmux: terminal multiplexing made simple
Using tmux to manage terminal sessions. Panes, windows, and why your SSH sessions should survive disconnects.