What is rsync?
rsync is a powerful tool for synchronizing and copying files in Linux and Unix systems. Its name comes from "remote sync" (remote synchronization).
For system administrators and WordPress users, rsync is the best way to quickly and efficiently copy files between servers and local machines, or between different servers.
🌐 Read the full article in Bulgarian: rsync команда в Linux - Пълно ръководство с примери
Why use rsync instead of FTP/SFTP?
- ✅ Copies only the changes, not entire files (saves time and bandwidth)
- ✅ Preserves permissions, timestamps, and file ownership
- ✅ Much faster than FTP – especially for WordPress with thousands of files
- ✅ Shows copy progress
- ✅ Can resume interrupted transfers
- ✅ Compresses data during transfer
- ✅ Perfect for backing up WordPress sites
Installation
Ubuntu/Debian:
sudo apt update
sudo apt install rsync
CentOS/RHEL/Rocky Linux:
sudo yum install rsync
Windows (WSL):
sudo apt update
sudo apt install rsync
Check if installed:
rsync --version
Basic Syntax - Understanding the Structure
rsync [OPTIONS] SOURCE DESTINATION
Anatomy of an rsync command - breaking it down
Let's look at a specific command and break it down:
rsync -avz root@10.20.20.23:/var/www/html/ /mnt/c/Users/fedia/Desktop/nav/
Breakdown:
-
rsync– the command itself (the program we're calling) -
-avz– OPTIONS/ARGUMENTS (how the command should work) -
root@10.20.20.23:/var/www/html/– SOURCE (where we're copying from) -
/mnt/c/Users/fedia/Desktop/nav/– DESTINATION (where we're copying to)
Understanding the OPTIONS (arguments)
rsync -avz ...
Options always start with - (dash) and can be:
Short options (combined):
-
-avz=-a+-v+-z(three options together) -
-avzhP=-a+-v+-z+-h+-P(five options together)
Long options (standalone):
-
--delete(with two dashes) -
--exclude(with two dashes)
Can we use NO options?
Yes! The simplest command is:
rsync /source/ /destination/
But this just copies files without preserving permissions, timestamps, etc. That's why we ALWAYS use at least -a.
Understanding the SOURCE
The source is WHERE we're copying from. It can be:
1. Local folder:
rsync -avz /home/user/documents/ /backup/
-
SOURCE:
/home/user/documents/ - Type: Local directory on the same machine
2. Remote folder (downloading from server):
rsync -avz root@10.20.20.23:/var/www/html/ /local/backup/
-
SOURCE:
root@10.20.20.23:/var/www/html/-
root– username on the server -
@– separator -
10.20.20.23– server IP address (can also be a domain) -
:– separator between server and path -
/var/www/html/– file path on the server
-
3. Alternative remote path format:
rsync -avz user@example.com:/home/user/files/ /local/
- Can use domain instead of IP
- Can use different user (not just root)
Understanding the DESTINATION
The destination is WHERE we're copying to. It can be:
1. Local folder:
rsync -avz root@server:/var/www/html/ /home/user/backup/
-
DESTINATION:
/home/user/backup/ - Type: Local directory on the same machine
2. Windows path in WSL:
rsync -avz root@server:/var/www/html/ /mnt/c/Users/fedia/Desktop/nav/
-
DESTINATION:
/mnt/c/Users/fedia/Desktop/nav/-
/mnt/c/= Windows C: drive - The rest is a normal Windows path
-
3. Remote folder (uploading to server):
rsync -avz /local/files/ root@server:/var/www/html/
-
DESTINATION:
root@server:/var/www/html/ - Type: Remote directory on a server
Rule for copy direction
Easy way to remember:
FROM → TO
Downloading (from server to local):
rsync -avz REMOTE LOCAL
rsync -avz root@server:/var/www/html/ /mnt/c/Users/fedia/Desktop/
Uploading (from local to server):
rsync -avz LOCAL REMOTE
rsync -avz /mnt/c/Users/fedia/Desktop/nav/ root@server:/var/www/html/
Critical rule for trailing slashes (/)
The trailing slash / at the end of the path drastically changes behavior!
WITH trailing slash (/) – copies CONTENTS:
rsync -avz /source/ /destination/
Result:
/destination/
├── file1.txt
├── file2.txt
└── subfolder/
Files from /source/ go DIRECTLY into /destination/
WITHOUT trailing slash (/) – copies THE FOLDER ITSELF:
rsync -avz /source /destination/
Result:
/destination/
└── source/
├── file1.txt
├── file2.txt
└── subfolder/
Creates a source folder inside destination
Real WordPress example:
# CORRECT - copies files directly
rsync -avz root@server:/var/www/html/ /backup/
# Result: /backup/wp-config.php, /backup/wp-content/, etc.
# WRONG - creates nested folder
rsync -avz root@server:/var/www/html /backup/
# Result: /backup/html/wp-config.php, /backup/html/wp-content/
Golden rule: Always use / at the end for more predictable behavior!
Real examples with full explanation
Example 1: Downloading a WordPress site
rsync -avz root@10.20.20.23:/var/www/html/ /mnt/c/Users/fedia/Desktop/nav/
Breakdown:
-
Command:
rsync -
Options:
-avz-
-a= archive mode (preserves everything) -
-v= verbose (shows what it's doing) -
-z= compression during transfer
-
-
Source:
root@10.20.20.23:/var/www/html/- Server:
10.20.20.23 - User:
root - Path:
/var/www/html/ -
/at end = copy contents
- Server:
-
Destination:
/mnt/c/Users/fedia/Desktop/nav/- Local path in WSL (Windows Desktop)
What it does: Downloads all files from /var/www/html/ on the server and places them in Desktop/nav/
Example 2: Uploading changes to server
rsync -avz /mnt/c/Users/fedia/Desktop/nav/ root@10.20.20.23:/var/www/html/
Breakdown:
-
Command:
rsync -
Options:
-avz(same as before) -
Source:
/mnt/c/Users/fedia/Desktop/nav/- Local path (Windows Desktop in WSL)
-
/at end = copy contents
-
Destination:
root@10.20.20.23:/var/www/html/- Remote server
What it does: Uploads files from local folder to server (reverse of example 1)
Example 3: Local copying (no network)
rsync -avh /home/user/website/ /backup/website-backup/
Breakdown:
-
Command:
rsync -
Options:
-avh-
-a= archive mode -
-v= verbose -
-h= human-readable sizes (shows MB/GB)
-
-
Source:
/home/user/website/(local folder) -
Destination:
/backup/website-backup/(another local folder)
What it does: Copies locally from one folder to another on the SAME machine
Example 4: With multiple options
rsync -avzhP --delete --exclude 'cache/' root@server:/var/www/html/ /backup/
Breakdown:
-
Command:
rsync -
Short options:
-avzhP-
-a= archive -
-v= verbose -
-z= compress -
-h= human-readable -
-P= progress + partial
-
-
Long options:
--delete --exclude 'cache/'-
--delete= delete files that don't exist in source -
--exclude 'cache/'= don't copy cache/ folder
-
-
Source:
root@server:/var/www/html/ -
Destination:
/backup/
What it does: Downloads files with synchronization (deletes unnecessary files) and skips the cache folder
Minimum required options
Can we use just rsync source destination?
Yes, but NOT recommended:
rsync /source/ /destination/
- Will copy files
- BUT won't preserve permissions, ownership, timestamps
- NOT recursive (won't enter subfolders)
Minimum for real work:
rsync -a /source/ /destination/
-
-ais the minimum necessary for proper copying
Recommended minimum:
rsync -av /source/ /destination/
-
-a= archive (preserves everything) -
-v= verbose (we see what's happening)
Optimal choice for daily use:
rsync -avz source destination
- For local copying:
-avh - For remote copying:
-avz(compression helps) - For large files:
-avzhP(we see progress)
Option combinations that always work together
# For backup (local)
rsync -avh source/ destination/
# For backup (remote)
rsync -avz root@server:/path/ /local/path/
# For synchronization (with deletion)
rsync -avz --delete source/ destination/
# For upload with progress
rsync -avzhP /local/ root@server:/remote/
# For excluding files
rsync -avz --exclude 'cache/' --exclude '*.log' source/ dest/
Most Important Arguments (Options)
Basic options:
| Option | Meaning | Explanation |
|---|---|---|
-a |
archive mode | Archive mode – preserves everything (permissions, times, links) |
-v |
verbose | Verbose output – shows what's being copied |
-z |
compress | Compresses data during transfer (faster transfer) |
-h |
human-readable | Shows sizes in readable format (KB, MB, GB) |
-P |
progress + partial | Shows progress + keeps partially copied files |
-n |
dry-run | "Test" mode – only shows what would happen |
-r |
recursive | Recursive – enters subdirectories |
-u |
update | Updates only newer files |
--delete |
delete | Deletes files that don't exist in source |
--exclude |
exclude | Excludes specific files/folders |
What does -a (archive) mean?
The -a option is actually a combination of:
-
-r– recursive copying -
-l– copies symbolic links -
-p– preserves permissions -
-t– preserves modification times -
-g– preserves group -
-o– preserves owner
For WordPress this is critically important – it preserves file permissions (644 for files, 755 for folders).
Practical WordPress Examples - Step by Step
1. Downloading a WordPress site from server (Backup)
Example 1: Basic download (Linux)
rsync -avz root@10.20.20.23:/var/www/html/ /home/user/wordpress-backup/
Explanation:
-
-a– archive mode (preserves permissions, times, etc.) -
-v– shows what's being copied -
-z– compresses data during transfer -
root@10.20.20.23– username and server IP address -
:/var/www/html/– path on server (note the/at the end!) -
/home/user/wordpress-backup/– local destination
What happens: All files from /var/www/html/ on the server are copied to the local folder /home/user/wordpress-backup/
Example 2: Download from WSL (Windows)
rsync -avz root@10.20.20.23:/var/www/html/ /mnt/c/Users/fedia/Desktop/nav/
Explanation:
- Same as above, but destination is a Windows path
-
/mnt/c/– this is how WSL sees the C: drive in Windows -
/mnt/c/Users/fedia/Desktop/nav/=C:\Users\fedia\Desktop\nav\
Example 3: Download with progress bar
rsync -avzhP root@10.20.20.23:/var/www/html/ /mnt/c/Users/fedia/Desktop/nav/
Explanation:
-
-P– shows progress bar for each file and overall percentage
Example 4: Download only wp-content (themes and plugins)
rsync -avz root@10.20.20.23:/var/www/html/wp-content/ /mnt/c/Users/fedia/Desktop/wp-content-backup/
Why only wp-content?
- Often we only need themes, plugins, and uploads
- Faster than the entire site
- WordPress core files can be downloaded from wordpress.org
2. Uploading a WordPress site to server (Deploy/Restore)
Example 1: Upload from local machine to server (Linux)
rsync -avz /home/user/wordpress-site/ root@10.20.20.23:/var/www/html/
Explanation:
- Reverse of downloading – local path is FIRST, server path is SECOND
- Copies local files to the server
Example 2: Upload from WSL (Windows)
rsync -avz /mnt/c/Users/fedia/Desktop/nav/ root@10.20.20.23:/var/www/html/
Explanation:
- Uploads files from Windows Desktop to the server
- Be careful with file permissions – you may need to correct them on the server after upload
Example 3: Upload with deletion of old files
rsync -avz --delete /home/user/wordpress-site/ root@10.20.20.23:/var/www/html/
Explanation:
-
--delete– deletes files on the server that DON'T exist locally - WARNING: Dangerous option! Use only if you're sure!
- Useful for "clean" synchronization
Example 4: "Test" upload (without actually copying)
rsync -avzn /home/user/wordpress-site/ root@10.20.20.23:/var/www/html/
Explanation:
-
-n(dry-run) – only shows what would be uploaded, WITHOUT actually uploading - Always do this first before real upload!
3. Copying between two servers
Example: WordPress migration from old to new server
# From server A to server B (execute from your local machine)
rsync -avz root@old-server:/var/www/html/ root@new-server:/var/www/html/
Explanation:
- Copies directly between two servers
- You're the intermediary – the command goes through your machine
4. Excluding unnecessary files (exclude)
WordPress contains many files we don't need in backups:
Example 1: Excluding cache folders
rsync -avz --exclude 'wp-content/cache/' \
--exclude 'wp-content/uploads/cache/' \
root@server:/var/www/html/ /mnt/c/Users/fedia/Desktop/backup/
Explanation:
-
--exclude– skips specific files/folders -
\– continues command on new line (for readability)
Example 2: Excluding multiple things
rsync -avz \
--exclude 'wp-content/cache/' \
--exclude 'wp-content/uploads/cache/' \
--exclude 'wp-content/backup*' \
--exclude '.git/' \
--exclude 'node_modules/' \
--exclude '.DS_Store' \
--exclude 'error_log' \
root@server:/var/www/html/ /mnt/c/Users/fedia/Desktop/backup/
What we're excluding:
-
cache/– cache folders (regenerated) -
backup*– old backup files -
.git/– Git repository (not needed in production) -
node_modules/– Node.js dependencies (huge and unnecessary) -
.DS_Store– Mac system files -
error_log– PHP error logs
Example 3: Using exclude file
Create a file rsync-exclude.txt:
wp-content/cache/
wp-content/uploads/cache/
wp-content/backup*
.git/
node_modules/
.DS_Store
error_log
*.log
Then:
rsync -avz --exclude-from='rsync-exclude.txt' \
root@server:/var/www/html/ /mnt/c/Users/fedia/Desktop/backup/
Typical WordPress Scenarios
Scenario 1: Daily backup
#!/bin/bash
# Script for automatic backup
DATE=$(date +%Y-%m-%d)
BACKUP_DIR="/home/user/backups/wordpress-$DATE"
rsync -avz \
--exclude 'wp-content/cache/' \
--exclude 'wp-content/uploads/cache/' \
root@server:/var/www/html/ "$BACKUP_DIR/"
echo "Backup completed in $BACKUP_DIR"
Scenario 2: Synchronizing uploads folder
Often we just want to download new upload files (images, PDFs, etc.):
rsync -avz --update root@server:/var/www/html/wp-content/uploads/ \
/home/user/wordpress-uploads/
Explanation:
-
--update– copies only newer files (saves time)
Scenario 3: Uploading only the theme (after development)
rsync -avz --delete /home/user/my-theme/ \
root@server:/var/www/html/wp-content/themes/my-theme/
Scenario 4: Synchronizing development and production
# Download production database and uploads
rsync -avz root@server:/var/www/html/wp-content/uploads/ \
/home/user/local-wordpress/wp-content/uploads/
Syntax Differences - Linux vs WSL
Linux (standard):
# Download
rsync -avz root@server:/var/www/html/ /home/user/backup/
# Upload
rsync -avz /home/user/backup/ root@server:/var/www/html/
WSL (Windows):
# Download
rsync -avz root@server:/var/www/html/ /mnt/c/Users/fedia/Desktop/backup/
# Upload
rsync -avz /mnt/c/Users/fedia/Desktop/backup/ root@server:/var/www/html/
Key difference:
- Linux:
/home/user/... - WSL:
/mnt/c/Users/...(for accessing Windows files)
Important Tips and Tricks
1. Always test with -n first!
# First - test mode
rsync -avzn /local/path/ root@server:/remote/path/
# If it looks good - without -n
rsync -avz /local/path/ root@server:/remote/path/
2. File permissions after rsync
After uploading files to a server, you may need to correct permissions:
# On the server
sudo chown -R www-data:www-data /var/www/html/
sudo find /var/www/html/ -type d -exec chmod 755 {} \;
sudo find /var/www/html/ -type f -exec chmod 644 {} \;
3. The trailing slash (/) is critical!
# With / - copies CONTENTS
rsync -avz /source/ /destination/
# Result: /destination/file1, /destination/file2
# WITHOUT / - copies THE FOLDER ITSELF
rsync -avz /source /destination/
# Result: /destination/source/file1, /destination/source/file2
4. SSH ports (if not 22)
rsync -avz -e "ssh -p 2222" root@server:/var/www/html/ /local/backup/
5. Show progress in human format
rsync -avzhP --stats root@server:/var/www/html/ /local/backup/
Shows:
- Progress bar for each file
- Total number of files
- Transferred bytes
- Transfer speed
Common Errors and Solutions
Error 1: "Permission denied"
Problem: You don't have rights to read/write files
Solution:
# Use sudo or connect as root
rsync -avz root@server:/var/www/html/ /local/backup/
Error 2: "Connection refused"
Problem: SSH isn't working or the port is wrong
Solution:
# Check SSH connection
ssh root@server
# If port is different
rsync -avz -e "ssh -p 2222" root@server:/path/ /local/
Error 3: Too many files being copied
Problem: Forgot to exclude cache/logs
Solution:
# Use --exclude
rsync -avz --exclude 'cache/' --exclude '*.log' root@server:/path/ /local/
Error 4: Files are copied again and again
Problem: Difference in timezones or permissions
Solution:
# Use --checksum to compare by content
rsync -avz --checksum root@server:/path/ /local/
Bonus: Useful Commands for WordPress
Check directory size before sync:
du -sh /var/www/html/
Count files:
find /var/www/html/ -type f | wc -l
Find largest files:
find /var/www/html/ -type f -exec du -h {} + | sort -rh | head -20
Conclusion
rsync is an indispensable tool for every WordPress administrator and system admin. Master it and you'll save hours of time when:
- Making backups
- Migrating between servers
- Synchronizing development and production
- Uploading changes after development
Golden rule: Always test with -n before real operations!
Most used command:
rsync -avzhP --exclude 'cache/' source/ destination/
This is all you need for 95% of cases! 🚀
💬 Join the Discussion
What's your rsync workflow? Do you use it for backups, deployments, or server migrations? Share your favorite rsync commands and use cases in the comments below!
📚 More Resources
🌐 Original article in Bulgarian: rsync команда в Linux - Пълно ръководство
🔧 Want more hands-on Linux guides and automation scripts?
Visit ITpraktika.com for:
- Linux command tutorials and cheat sheets
- Bash scripting and automation guides
- Server administration best practices
- WordPress optimization tips
- Proxmox and Docker tutorials
- And much more!
If you found this helpful, check out more practical Linux content at itpraktika.com 🚀
Top comments (0)