Rsync: File Synchronisation and Backups on Linux

Rsync copies files between directories and servers and transfers only what has changed. Re-syncing a large directory takes seconds, and an interrupted transfer can be resumed where it stopped. It is the main tool for moving sites and making backups on Linux.
Installation
Most distributions ship rsync by default. If not:
sudo apt install rsync # Ubuntu, Debian
sudo dnf install rsync # AlmaLinux, Rocky Linux
To copy between servers, rsync must be installed on both sides.
Syntax
rsync [options] source destination
The most common form:
rsync -av /var/www/site/ /backup/site/
-a— archive mode: recursive, preserving permissions, owners, modification times and symlinks;-v— show the files being transferred.
The trailing slash
This is the most common source of mistakes. A trailing slash on the source changes the result:
rsync -av /var/www/site/ /backup/ # copies the contents of site into /backup/
rsync -av /var/www/site /backup/ # creates the directory /backup/site/
An easy way to remember it: with a slash you copy the directory’s contents, without it you copy the directory itself.
Dry run
Before any serious operation, check what the command will actually do. The -n (or --dry-run) option lists the actions without changing anything:
rsync -avn --delete /var/www/site/ /backup/site/
Copying to a remote server
Rsync works over SSH; no separate setup is needed.
Send a directory to a server:
rsync -avz /var/www/site/ user@203.0.113.10:/backup/site/
Fetch a directory from a server:
rsync -avz user@203.0.113.10:/var/www/site/ /backup/site/
The -z option compresses data in transit — useful for text files on a slow link. If SSH runs on a non-standard port or you need a specific key:
rsync -avz -e "ssh -p 2222 -i ~/.ssh/id_ed25519" /var/www/site/ user@203.0.113.10:/backup/site/
If the server is described in ~/.ssh/config, as shown in the SSH connection guide, its short name is enough.
Useful options
| Option | What it does |
|---|---|
-P |
show progress and resume interrupted files |
--delete |
delete files at the destination that no longer exist at the source |
--exclude='*.log' |
skip files matching a pattern |
--exclude-from=file |
read the exclude list from a file |
--bwlimit=5000 |
limit the speed, in kilobytes per second |
-h |
print sizes in human-readable form |
--stats |
print a summary at the end |
-c |
compare files by checksum instead of size and time |
Excludes
rsync -av --exclude='cache/' --exclude='*.tmp' --exclude='.git/' /var/www/site/ /backup/site/
Patterns are relative to the source. For a long list, a file is more convenient:
rsync -av --exclude-from=/etc/rsync-exclude.txt /var/www/site/ /backup/site/
Scheduled backups
Create the script /usr/local/bin/backup-site.sh:
#!/bin/bash
rsync -az --delete \
--exclude='cache/' \
/var/www/site/ backup@203.0.113.20:/backup/site/ \
>> /var/log/backup-site.log 2>&1
Make it executable and add a cron job:
chmod +x /usr/local/bin/backup-site.sh
crontab -e
30 3 * * * flock -n /tmp/backup-site.lock /usr/local/bin/backup-site.sh
To run without a password prompt, set up SSH key login with no passphrase and restrict that key’s rights on the backup server.
Backups with history
Plain synchronisation keeps only the latest state: if a file gets corrupted, the corrupted version reaches the copy as well. The --link-dest option creates daily snapshots in which unchanged files are hard links and take no extra space:
TODAY=$(date +%F)
rsync -a --delete --link-dest=/backup/latest /var/www/site/ /backup/$TODAY/
ln -sfn /backup/$TODAY /backup/latest
Each dated directory looks like a full copy, while disk space is spent only on changes.
Moving a site between servers
rsync -avzP --delete /var/www/site/ root@203.0.113.30:/var/www/site/
Run the command in advance, then once more right before switching DNS: the second sync transfers only the changes and takes very little time. You can test the site on the new server before changing DNS.
Common errors
Permission denied— the user cannot read the source or write to the destination. Run rsync as root for system files.rsync: command not foundon the remote side — rsync is not installed on the second server.- Files are copied again on every run — modification times are not preserved. Use
-a, not just-r. - File owners changed — only root can preserve ownership. When copying as a regular user, the files end up owned by that user.
Choosing a backup tool
Rsync is a good fit for mirroring a directory. For backups with encryption, compression and deduplication, dedicated tools such as Borg Backup are more convenient. Keep the copies away from the main server, on separate backup storage.


