Linux7 min read

rsync: the Swiss Army knife of file sync

linuxrsyncbackupfile-synccli

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