Skip to main content
Blog|
Learning center

rsync Commands: A Complete Reference Guide

|
Mar 18, 2026|11 min read
LEARNING CENTERrsync Commands: A CompleteReference GuideHOSTNEYhostney.comMarch 18, 2026

rsync copies and synchronizes files between two locations. It can work locally (one directory to another on the same machine) or remotely over SSH. What makes rsync different from tools like SCP is that it only transfers the differences between source and destination. If you sync a 500 MB directory and change one file, rsync transfers only that file. If you change 10 bytes in a large file, rsync can transfer only the changed blocks.

This makes rsync the standard tool for backups, deployments, directory mirroring, and any recurring transfer where most of the data has not changed since the last run.

This guide covers rsync syntax, every commonly used flag with practical examples, and how rsync compares to SCP and SFTP. It is structured as a reference – jump to the flag you need. For a practical tutorial focused on directory-to-directory syncing with real examples, see How to sync directories with rsync.

Basic syntax#

rsync [options] source destination

Either the source or destination can be remote. Remote paths use the format user@host:path (same as SCP). rsync uses SSH for remote transfers by default.

# Local to local
rsync -av /home/user/project/ /backup/project/

# Local to remote
rsync -av /home/user/project/ user@example.com:/var/www/html/

# Remote to local
rsync -av user@example.com:/var/www/html/ /home/user/backup/

Trailing slash matters

This is the most common source of confusion with rsync.

With trailing slash on source: copies the contents of the directory.

rsync -av /home/user/project/ /backup/project/

Result: files from inside project/ go directly into /backup/project/ .

Without trailing slash on source: copies the directory itself.

rsync -av /home/user/project /backup/

Result: creates /backup/project/ and puts the files inside it.

The trailing slash means “the contents of this directory.” No trailing slash means “this directory and its contents.” Getting this wrong either nests directories one level too deep or flattens them one level too shallow. When in doubt, use --dry-run first.

Archive mode (-a)#

Archive mode is the flag you will use on nearly every rsync command. It is a shorthand that combines several flags into one:

rsync -a source/ destination/

-a is equivalent to -rlptgoD :

FlagWhat it does
-r Recursive (include subdirectories)
-l Copy symlinks as symlinks
-p Preserve permissions
-t Preserve modification times
-g Preserve group ownership
-o Preserve owner
-D Preserve device files and special files

Archive mode preserves the directory structure and metadata of your files. The destination ends up as close to an exact copy of the source as possible. This is what you want for backups, migrations, and most sync operations.

Without -a , rsync does not recurse into subdirectories and does not preserve permissions, timestamps, or ownership. You almost never want that.

When archive mode is not enough

Archive mode does not preserve:

  • Hard links. Use  -H  to preserve hard links. This is slower because rsync has to track all inodes.
  • ACLs (Access Control Lists). Use  -A  to preserve ACLs.
  • Extended attributes. Use  -X  to preserve xattrs.

For a truly exact copy:

rsync -aHAX source/ destination/

Most web hosting scenarios do not need -H , -A , or -X . Plain -a is sufficient.

Verbose output (-v)#

Shows what rsync is doing:

rsync -av source/ destination/

Output:

sending incremental file list
wp-config.php
wp-content/uploads/2024/photo.jpg
wp-content/themes/mytheme/style.css

sent 45,230 bytes  received 1,234 bytes  30,976.00 bytes/sec
total size is 52,428,800  speedup is 1,128.32

Each line is a file being transferred. Files that have not changed are not listed. The summary at the end shows how much data was actually sent versus the total size of all files – the “speedup” number tells you how effective the incremental transfer was.

Double verbose (-vv)

rsync -avv source/ destination/

Shows skipped files too, along with the reason they were skipped (unchanged, excluded, etc.). Useful for debugging when you expect a file to transfer but it does not.

Dry run (-dry-run or -n)#

Shows what rsync would do without actually doing it:

rsync -avn source/ destination/

or equivalently:

rsync -av --dry-run source/ destination/

This is essential before running any rsync with --delete or other destructive flags. Always preview first.

Compression (-z)#

Compresses data during transfer:

rsync -avz source/ user@example.com:/backup/

This reduces the amount of data sent over the network. Useful for remote transfers over slow connections. The compression happens in transit only – files are stored uncompressed at the destination.

Compression helps with text files, uncompressed data, and database dumps. It has minimal effect on already-compressed files (ZIP, gzip, JPEG, PNG). For transfers that are mostly compressed files, -z adds CPU overhead without meaningful bandwidth savings.

Progress display (-P)#

Shows transfer progress for each file:

rsync -avP source/ destination/

Output:

large-file.zip
    125,952,000  45%   12.50MB/s    0:00:08

-P is a shorthand for --partial --progress :

  • --progress  shows the per-file progress bar
  • --partial  keeps partially transferred files. If a transfer is interrupted, rsync can resume from where it left off instead of starting over

For large file transfers, -P is almost always worth adding. Without --partial , an interrupted transfer of a 2 GB file means starting that file from zero on the next run.

itemize-changes (-i)

For a more detailed view of what changed:

rsync -avi source/ destination/

Output:

>f..t...... wp-config.php
>f.st...... wp-content/uploads/photo.jpg
cd+++++++++ wp-content/new-directory/

Each character position means something: f = file, d = directory, s = size changed, t = timestamp changed, + = newly created. This is useful for auditing exactly what changed between two directory trees.

Recursive (-r)#

Copies subdirectories:

rsync -r source/ destination/

You rarely need -r on its own because -a includes it. The only time to use -r without -a is when you specifically do not want to preserve permissions, timestamps, or ownership – for example, when copying files to a filesystem that does not support Unix permissions (like some Windows shares or FAT32 drives).

Delete files at destination (-delete)#

By default, rsync only adds and updates files. It never deletes anything at the destination. If you remove a file from the source, it remains at the destination after the next sync.

--delete removes files at the destination that no longer exist at the source:

rsync -av --delete source/ destination/

This makes the destination an exact mirror of the source. Files that exist in the destination but not in the source are deleted.

Use –dry-run first. Always preview what will be deleted before running this:

rsync -avn --delete source/ destination/

Lines starting with deleting show what would be removed.

Delete variants

–delete-before: deletes files at the destination before transferring new files. Uses more memory but ensures the destination has enough space.

–delete-after: deletes files after transferring. The default when using --delete .

–delete-during: deletes files as rsync encounters them during the transfer. More efficient for large directory trees.

–delete-excluded: also deletes files at the destination that match your --exclude patterns. Without this, excluded files are left alone at the destination even if they do not exist at the source.

Excluding files (-exclude)#

Skip files matching a pattern:

rsync -av --exclude '*.log' source/ destination/

Multiple exclusions

rsync -av --exclude '*.log' --exclude '*.tmp' --exclude '.git' source/ destination/

Exclude from a file

For complex exclusion lists, put patterns in a file:

rsync -av --exclude-from='exclude-list.txt' source/ destination/

Where exclude-list.txt contains:

*.log
*.tmp
.git
node_modules
.env
wp-content/cache
wp-content/uploads/backup*

One pattern per line. Lines starting with # are comments.

Including files (–include)

Combine --include and --exclude for fine-grained control:

rsync -av --include '*.php' --exclude '*' source/ destination/

This copies only .php files. The order matters – rsync processes rules in order and applies the first match.

Common exclusion patterns for WordPress

rsync -av \
  --exclude '.git' \
  --exclude 'node_modules' \
  --exclude 'wp-content/cache' \
  --exclude 'wp-content/debug.log' \
  --exclude '.env' \
  source/ destination/

Bandwidth limiting (-bwlimit)#

Limit transfer speed to avoid saturating your connection:

rsync -avz --bwlimit=5000 source/ user@example.com:/backup/

The value is in KBytes per second. 5000 = approximately 5 MB/s. Useful for production server backups where you do not want the transfer to consume all available bandwidth and affect site performance.

Specifying SSH options (-e)#

rsync uses SSH for remote transfers by default. To specify SSH options:

Non-standard SSH port

rsync -av -e "ssh -p 2222" source/ user@example.com:/backup/

For more on SSH ports, see What port does SSH use.

Specific SSH key

rsync -av -e "ssh -i ~/.ssh/id_ed25519" source/ user@example.com:/backup/

Combined SSH options

rsync -av -e "ssh -p 2222 -i ~/.ssh/id_ed25519" source/ user@example.com:/backup/

If you have these settings in your SSH config file ( ~/.ssh/config ), you do not need the -e flag – rsync picks them up automatically. See How to set up passwordless SSH login for SSH config setup.

Preserving permissions and ownership#

Archive mode ( -a ) preserves permissions, ownership, and timestamps by default. But there are cases where you want to override this.

Do not preserve ownership (–no-owner –no-group)

When copying to a server where you are not root, preserving ownership fails because only root can set file ownership to arbitrary users:

rsync -av --no-owner --no-group source/ user@example.com:/var/www/html/

Files are created with the receiving user’s default ownership.

Set specific permissions (–chmod)

Override permissions on the destination:

rsync -av --chmod=D755,F644 source/ destination/

D755 sets directories to 755 (owner rwx, others rx). F644 sets files to 644 (owner rw, others r). This is the standard WordPress permission scheme.

Comparing without transferring (-checksum)#

By default, rsync compares files by size and modification time. If both match, the file is skipped. This is fast but can miss changes if a file was modified without changing its size or timestamp (rare, but possible).

--checksum forces rsync to compare file checksums:

rsync -avc source/ destination/

or:

rsync -av --checksum source/ destination/

This is slower because rsync has to read and checksum every file on both sides, but it catches every difference regardless of timestamps. Useful for verification runs after a migration.

Human-readable output (-h)#

Makes file sizes readable:

rsync -avh source/ destination/

Output shows 45.23MB instead of 47,433,728 . Combine with other flags for readable progress:

rsync -avhP source/ destination/

Practical examples#

Backup a WordPress site

rsync -avz --exclude 'wp-content/cache' \
  user@example.com:/var/www/html/ \
  /home/user/backups/wordpress/

Downloads the entire WordPress installation, excluding the cache directory. Run it again later and only changed files transfer.

Deploy code to a server

rsync -avz --delete \
  --exclude '.git' \
  --exclude '.env' \
  --exclude 'node_modules' \
  /home/user/project/ \
  user@example.com:/var/www/html/

Syncs your local project to the server. --delete removes files on the server that you deleted locally. The exclusions prevent development artifacts from being deployed.

Mirror two directories locally

rsync -av --delete /data/primary/ /data/mirror/

Makes /data/mirror/ an exact copy of /data/primary/ . Files added to primary appear in mirror. Files deleted from primary are deleted from mirror.

Transfer with bandwidth limit during business hours

rsync -avz --bwlimit=2000 \
  user@source-server.com:/var/www/html/ \
  /home/user/migration/

Limits the transfer to 2 MB/s so it does not affect site performance while users are active.

Resume an interrupted transfer

rsync -avP user@example.com:/backup/large-database.sql.gz .

If the transfer is interrupted, run the same command again. --partial (included in -P ) keeps the incomplete file, and rsync resumes from where it stopped.

Sync only specific file types

rsync -av --include '*/' --include '*.php' --exclude '*' \
  source/ destination/

The --include '*/' is necessary to make rsync recurse into directories. Without it, rsync excludes the directories themselves and never finds the .php files inside them.

Verify a previous sync

rsync -avnc source/ destination/

Dry run with checksum comparison. Shows any files that differ between source and destination without transferring anything. Useful for verifying that a backup or migration completed correctly.

rsync vs SCP vs SFTP#

All three transfer files over SSH. They serve different purposes.

rsync

Designed for synchronization. Compares source and destination, transfers only differences. Handles interrupted transfers, supports exclusions, can delete files at the destination. The right tool for recurring transfers, backups, and deployments.

SCP

Copies files from A to B. No comparison, no incremental transfer, no exclusions. Every run transfers everything. Simpler syntax for one-off file copies. See How to transfer files over SSH using SCP for the full reference.

SFTP

Interactive file management session. Browse directories, upload, download, rename, delete, change permissions. More like a remote file manager than a sync tool. See the SFTP commands reference.

Comparison

rsyncSCPSFTP
Transfer typeIncremental (only differences)Full copyFull copy
Resume supportYes (with –partial)NoPartial (append)
Delete at destinationYes (with –delete)NoManual only
Exclude filesYesNoNo
InteractiveNoNoYes
Best forRecurring sync, backups, deploymentsQuick one-off file copiesInteractive file management

When to use which

rsync when you need to keep two locations in sync, when you transfer the same directory repeatedly, when you need exclusions, or when transfers are large enough that incremental sync saves meaningful time.

SCP when you need to copy a single file or a small set of files and you already know the paths. Simpler syntax, no configuration needed.

SFTP when you need to browse the remote filesystem, manage files interactively, or hand someone a GUI tool for file management.

Installing rsync#

rsync is pre-installed on most Linux distributions and macOS. Check with:

rsync --version

Ubuntu/Debian

sudo apt update && sudo apt install rsync

CentOS/RHEL

sudo dnf install rsync

macOS

Included by default. For a newer version:

brew install rsync

Windows

rsync is not natively available on Windows. Options:

  • WSL (Windows Subsystem for Linux): install a Linux distribution through WSL and use rsync normally
  • Cygwin: includes rsync in its package repository
  • cwRsync: a standalone Windows port of rsync

For simple file transfers on Windows without rsync, SCP is built into Windows 10 and 11 via OpenSSH.

rsync on Hostney#

On Hostney, rsync works over SSH with your account credentials. Every account has SSH access inside an isolated container, and rsync uses the same connection.

Connect using:

  • Host: your server hostname from the control panel
  • Port: 22
  • Username: your account username
  • Authentication: SSH key (configured through the SSH Keys section in the control panel)

Example backup of your WordPress site:

rsync -avz user@your-server.hostney.com:/var/www/html/ /home/localuser/backups/

SSH key authentication is required. See How to set up passwordless SSH login if you have not configured your key yet. Your connection details are shown under Terminal Access in the control panel.

Quick reference#

CommandWhat it does
rsync -av src/ dest/ Archive mode, verbose
rsync -avz src/ user@host:/path/ Compressed transfer over SSH
rsync -avP src/ dest/ Show progress, keep partial files
rsync -avn src/ dest/ Dry run (preview without transferring)
rsync -av --delete src/ dest/ Mirror source to destination (delete extras)
rsync -av --exclude '*.log' src/ dest/ Exclude files matching pattern
rsync -av --bwlimit=5000 src/ dest/ Limit bandwidth to 5 MB/s
rsync -av -e "ssh -p 2222" src/ user@host:/path/ Use non-standard SSH port
rsync -av --chmod=D755,F644 src/ dest/ Set permissions on destination
rsync -avc src/ dest/ Compare by checksum instead of time/size
rsync -avhP src/ dest/ Human-readable sizes with progress