ZetCode

Linux rsync Command

last modified October 18, 2026

The rsync command synchronizes files and directories between two locations. By default, it skips files whose size and modification time match. Remote transfers normally use a delta-transfer algorithm for changed files, while local copies normally transfer changed files in full. This can make repeated synchronization faster than copying an entire directory tree. This tutorial covers basic and advanced usage of rsync with practical examples.

rsync is commonly used for backups, deploying web sites, keeping directories in sync, and transferring files to remote servers over SSH.

Copy a Directory Locally

The -a (archive) option enables recursive copying and preserves most file attributes. The -v option prints the files being transferred.

rsync_basic.sh
$ rsync -av source/ destination/
sending incremental file list
created directory destination
./
readme.txt
docs/
docs/manual.txt
logs/
logs/app.log

The trailing slash on source/ matters. It copies the contents of the source directory into destination/. Without the slash, rsync -av source destination/ creates destination/source/ instead.

Perform a Dry Run

The --dry-run option shows what would happen without changing any files. Use it before a large transfer or before enabling deletion.

rsync_dry_run.sh
$ rsync -av --dry-run source/ destination/
sending incremental file list
readme.txt
docs/
docs/manual.txt
logs/
logs/app.log

sent 199 bytes  received 33 bytes  464.00 bytes/sec
total size is 6,006  speedup is 25.89 (DRY RUN)

The output lists the files that would be copied, updated, or deleted. A dry run performs the same comparison as a real transfer but writes nothing to the destination.

Mirror a Directory with --delete

The --delete option removes files from the destination that no longer exist in the source within the directories being synchronized. Excluded destination files are normally protected from deletion, so the result is not necessarily an exact mirror. --delete-excluded changes that behavior by also deleting excluded destination files.

rsync_delete.sh
$ rsync -av --delete source/ destination/
sending incremental file list
deleting old-file.txt

--delete can remove important data. Always combine it with --dry-run first, and make sure the source path is correct. A mistaken trailing slash or an empty source directory can erase the destination.

Exclude Files and Directories

The --exclude option skips paths that match a pattern. It can be repeated for several patterns.

rsync_exclude.sh
$ rsync -av --exclude='*.log' --exclude='cache/' source/ destination/
sending incremental file list
./
readme.txt
docs/
docs/manual.txt

Patterns are matched against the path relative to the transfer root. Quote them so the shell does not expand them. Use --include before a broad --exclude when you need to keep specific files.

Show Transfer Progress

The --progress option displays per-file progress, transfer speed, and estimated time.

rsync_progress.sh
$ rsync -av --progress source/ destination/
readme.txt
              6 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=3/5)
docs/
docs/manual.txt
          5,000 100%    4.77MB/s    0:00:00 (xfr#2, to-chk=2/5)

Progress output is part of the normal standard output. For unattended jobs, use --info=progress2 to show overall progress instead of one line per file.

Synchronize over SSH

Use a remote shell such as SSH to synchronize with another machine. The -z option compresses data during the transfer.

rsync_ssh.sh
$ rsync -avz -e ssh source/ jano@example.com:/srv/backup/

rsync must be installed on both machines. The remote path uses the usual user@host:path syntax. If you have a host alias in ~/.ssh/config, use it in place of the user and host name.

Understand Archive Mode

The -a option is a shortcut for -rlptgoD: recursive, copy symlinks as symlinks, preserve permissions and modification times, preserve group and owner, and preserve device and special files. It is the usual choice for backups.

rsync_archive.sh
$ rsync -a source/ destination/

Archive mode does not preserve hard-link relationships, ACLs, or extended attributes. Add -H for hard links, -A for ACLs, and -X for extended attributes when supported by the file system. Ownership preservation usually requires root.

Compare File Contents with Checksums

By default, rsync decides whether a file has changed from its size and modification time. The -c option compares checksums instead.

rsync_checksum.sh
$ rsync -acni source/ destination/

Checksum mode requires additional disk reads to hash file contents rather than relying only on size and modification time. Here, -n performs a dry run and -i itemizes the changes that would be made, including metadata changes requested by archive mode. Without -n, the command performs synchronization.

Destination-only files are not reported by this command. Add --delete to the dry run to see which destination entries would be removed, subject to any exclusion rules.

Keep Backups of Changed Files

The --backup option keeps a copy of files before they are overwritten or deleted. The --suffix option sets the backup suffix.

rsync_backup.sh
$ rsync -av --backup --suffix=.bak source/ destination/

Backups are stored next to the original file in the destination. Use --backup-dir to collect them in a separate directory instead. This is not a replacement for a full versioned backup strategy, but it prevents accidental overwrites during a sync.

Limit Bandwidth

The --bwlimit option caps the transfer rate. An unsuffixed value is measured in KiB per second, so --bwlimit=1000 requests a limit of 1000 KiB/s.

rsync_bandwidth.sh
$ rsync -av --bwlimit=1000 source/ jano@example.com:/srv/backup/

The value is a maximum, not a reservation. Limiting bandwidth is useful on shared links or when the transfer must not interfere with interactive traffic.

Best Practices for rsync

Source

Linux rsync Manual

In this article, we have explored various examples of using the rsync command for local copies, dry runs, mirroring, excludes, remote transfers, and backups.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.