How to Use rsync for Fast File Synchronization

Learn how to use rsync for fast, reliable file synchronization on Linux. Step-by-step examples and practical tips for DevOps beginners to sync files, preserve permissions, and speed up transfers.

How to Use rsync for Fast File Synchronization

Short introduction: rsync is a fast, versatile file-copying tool commonly used for backups, mirroring, and syncing between machines. This guide walks through practical examples and options so you can start syncing reliably and efficiently today.

Basic rsync usage and important flags

At its simplest, rsync copies files from a source to a destination. The most commonly used options for everyday syncing are:

  • -a : archive mode (recursive, preserves permissions, timestamps, symbolic links, etc.)
  • -v : verbose
  • -P : shows progress and keeps partial transfers (equivalent to --partial --progress)
  • -z : compress file data during transfer
  • --delete : remove files on the destination that were deleted on the source

Example — copy a directory locally:

# Copy /home/user/data/ to /mnt/backup/data/, preserving attributes and showing progress
rsync -avP /home/user/data/ /mnt/backup/data/

Notes:

  • The trailing slash on the source matters: /src/dir/ copies the contents of dir into the destination; /src/dir copies the dir itself into the destination path.

Use --dry-run (or -n) to preview actions without changing anything:

rsync -avPn /home/user/data/ /mnt/backup/data/

Local and remote synchronization

rsync is powerful for both local filesystem copies and remote transfers over SSH (the default remote transport). Use rsync to copy to/from remote hosts securely.

Example — push local folder to remote host:

# Copy local folder to remote host (username@remote:/path)
rsync -avzP /home/user/data/ user@example.com:/home/user/backup/data/

Example — pull from remote host to local:

# Copy remote folder back to local machine
rsync -avzP user@example.com:/home/user/backup/data/ /home/user/data_restored/

If your remote SSH uses a nonstandard port:

rsync -avzP -e "ssh -p 2222" /home/user/data/ user@example.com:/backups/data/

Tips:

  • Add --delete to mirror deletions from source to destination, but use --dry-run first.
  • For very large trees or slow links, --bwlimit=KBPS can throttle bandwidth.

Advanced tips: excludes, dry-run, partial transfers, and incremental backups

Real-world syncing often needs exclusions, atomic snapshots, or partial transfer handling. Here are practical options and patterns.

Exclude patterns (single pattern and file list):

# Exclude patterns on the command line
rsync -av --exclude='*.cache' --exclude='node_modules/' /src/ /dst/

# Exclude patterns from a file (one pattern per line)
rsync -av --exclude-from='/home/user/rsync-exclude.txt' /src/ /dst/

Dry-run and verbose before committing:

# Preview what would happen (safe first step)
rsync -avPn --delete /home/user/data/ /mnt/backup/data/

Partial/Resuming transfers:

# Keep partially transferred files so interrupted transfers can resume
rsync -avP --partial /large/files/ /mnt/backup/large_files/

Incremental snapshot-style backups using hard links:

# Create a dated snapshot using --link-dest to hardlink unchanged files from previous snapshot
# Assumes /backups/latest exists (previous snapshot)
TODAY=$(date +%F)
rsync -av --delete --link-dest=/backups/latest /home/user/data/ /backups/$TODAY/
# Then update 'latest' symlink
rm -f /backups/latest
ln -s /backups/$TODAY /backups/latest

This technique lets you keep multiple snapshots without doubling disk usage — unchanged files are hardlinked to the previous snapshot.

Scheduling and making rsync robust

For regular backups you’ll want unattended, repeatable runs and logging. Use cron/systemd timers and robust options to avoid partial or overlapping runs.

Example cron entry (runs daily at 2:30 AM and logs output):

30 2 * * * /usr/bin/rsync -a --delete /home/user/data/ /mnt/backup/data/ >> /var/log/rsync-backup.log 2>&1

Avoid overlapping runs (simple lockfile example in a wrapper script):

#!/bin/bash
LOCKFILE=/var/run/rsync-backup.lock
if [ -e "$LOCKFILE" ] && kill -0 "$(cat $LOCKFILE)" 2>/dev/null; then
  echo "Backup already running"; exit 1
fi
echo $$ > "$LOCKFILE"
rsync -a --delete /home/user/data/ /mnt/backup/data/ >> /var/log/rsync-backup.log 2>&1
rm -f "$LOCKFILE"

If running long transfers over unstable networks, combine --partial with --inplace or use --partial-dir to control where partial data is stored. Prefer --partial-dir for cleaner partial handling:

rsync -a --partial --partial-dir=.rsync-partial /home/user/data/ user@remote:/backups/data/

Common Pitfalls

  • Trailing slash confusion
    • Mistake: copying /src/dir vs /src/dir/ can produce different destination layouts.
    • Example to check: rsync -av /src/dir /dst/ vs rsync -av /src/dir/ /dst/
  • Accidentally deleting files with --delete
    • Always run a dry-run first: rsync -avPn --delete /src/ /dst/
  • Permissions and ownership surprises when running as different users
    • If you expect to preserve ownership, run as root or use appropriate permissions. For remote transfers, user differences may change ownership on destination unless you have uid/gid alignment or root access.

Example showing trailing slash issue in practice:

# Copies the directory 'dir' INTO /dst (result: /dst/dir/...)
rsync -av /src/dir /dst/

# Copies CONTENTS of 'dir' INTO /dst (result: /dst/...)
rsync -av /src/dir/ /dst/

Next Steps

  • Try a dry-run sync: rsync -avPn /path/to/source/ /path/to/destination/ to confirm behavior before changing files.
  • Implement daily backups with a cron job or systemd timer and log outputs for monitoring.
  • Explore snapshot backups with --link-dest to keep efficient historical snapshots without duplicating unchanged files.

If you run into a specific use case (e.g., Windows clients, rsync daemon mode, or preserving ACLs/xattrs), mention it and you’ll get tailored examples.

👉 Explore more IT books and guides at dargslan.com.