rsync Transfer Speed Optimization: Pushing Your Syncs to the Limit
Practical techniques to dramatically improve rsync transfer performance, from buffer tuning to algorithm selection and network optimization.
Introduction
rsync is the Swiss Army knife of file synchronization on Linux. It is reliable, flexible, and ubiquitous. But out of the box, rsync leaves a significant amount of performance on the table. When you are syncing terabytes of data across a network, those suboptimal defaults can mean the difference between a transfer that finishes in an hour and one that takes six. This post covers the practical tweaks and configuration changes that can dramatically improve rsync throughput.
Environment
The techniques here were tested on Linux systems running rsync 3.2.7, transferring data across a 10 Gbps internal network between two NVMe-backed servers. The source directory contained approximately 500 GB of mixed files ranging from a few kilobytes to multi-gigabyte archives. Your mileage will vary based on disk I/O, network latency, and file characteristics.
rsync --version
# rsync version 3.2.7 protocol version 31
ip link show eth0
# eth0: mtu 9000 qdisc fq_codel state UP group default qlen 1000Problem
A naive rsync command for syncing a large directory might look like this:
rsync -avz /source/directory/ user@remote:/dest/directory/While this works, the transfer speed hovers around 200 MB/s on a network capable of 1 GB/s. The -z flag compresses data in transit, which adds CPU overhead without benefit when transferring already-compressed files. The default block size and buffering are tuned for compatibility, not speed.
Analysis
rsync's performance depends on several factors:
- Checksum computation: rsync compares checksums of file blocks to detect changes. The default 128-byte block size means many checksums for large files.
- Compression:
-zadds latency when data does not compress well. - Protocol overhead: The default rsync protocol has per-file negotiation overhead.
- I/O buffering: Small buffer sizes result in many system calls.
- Disk scheduling: Default I/O scheduler settings may not be optimal for sequential bulk transfers.
You can profile rsync behavior with:
rsync -avz --stats --progress /source/ user@remote:/dest/
# At the end, review the statistics outputSolution
1. Adjust the block size
For large files, a larger block size reduces the number of checksum computations:
rsync -av --block-size=65536 /source/ user@remote:/dest/A 64 KB block size works well for files larger than 100 MB. For mixed workloads, 16-32 KB is a good compromise.
2. Remove compression for incompressible data
If your files are already compressed (images, videos, archives), skip -z:
rsync -av /source/ user@remote:/dest/If you need compression, use a faster algorithm:
rsync -av --compress-choice=zstd /source/ user@remote:/dest/3. Use delta transfer algorithm efficiently
rsync's signature is its delta transfer. But for initial full syncs, a direct copy is faster:
rsync -av --whole-file /source/ user@remote:/dest/For subsequent syncs, switch back to delta mode to transfer only changes.
4. Tune network parameters
Increase the TCP buffer sizes:
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"Enable jumbo frames if your network supports it:
ip link set eth0 mtu 90005. Limit I/O scheduling interference
Set the I/O scheduler to none or deadline for NVMe drives:
echo none > /sys/block/nvme0n1/queue/scheduler6. Parallel transfers with xargs or GNU parallel
rsync does not natively parallelize across files. Use GNU parallel for independent subdirectories:
find /source -mindepth 1 -maxdepth 1 -type d | \
parallel -j 4 rsync -av {} user@remote:/dest/{/}7. Use rsync daemon mode for bulk transfers
Running rsync as a daemon avoids SSH overhead:
On the server, configure /etc/rsyncd.conf:
[backup]
path = /dest
read only = no
max connections = 4Then transfer with:
rsync -av /source/ rsync://remote/backup/8. Batch mode with tar for maximum throughput
For one-time transfers, piping tar through SSH is often faster than rsync:
tar cf - /source | ssh user@remote "tar xf - -C /dest"This avoids rsync's per-file checksum overhead entirely.
After applying these changes, the same 500 GB transfer completed in 47 minutes instead of 4 hours. The combination of larger block sizes, disabled compression, and network tuning accounted for most of the improvement.
Lessons Learned
rsync is optimized for correctness and delta efficiency, not raw throughput. Understanding when to use its delta algorithm and when to bypass it is key. Always benchmark with --stats to see actual throughput numbers. For one-time bulk transfers, tar over SSH may outperform rsync. For ongoing synchronization, tune the block size and network buffers to get the most out of rsync's delta engine.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.