Rsync Slow Over WAN? A Bottleneck-First Tuning Guide
Diagnose slow rsync transfers over a WAN, reduce unnecessary scans and checksums, test compression safely, and benchmark large and small files.
When rsync is slow over a WAN, the network is only one of the places where the time can go. An rsync job can spend a long time scanning directories before it sends much data, or transfer quickly and then wait on destination writes. If you treat the whole job as a network problem, changes to SSH or bandwidth may leave the delay untouched.
Start by timing file-list creation, change detection, payload transfer, and completion. The steps below explain which rsync settings affect each phase and how to compare one large file with a representative folder. The examples assume rsync over SSH; check both installed versions before using version-specific options.
What rsync does before it sends data
Rsync is a file-copy and synchronization tool, not only a byte stream. Its default quick check compares file size and modification time to decide which files need data transfer. When a destination file can be used as a basis, rsync’s delta-transfer algorithm can send changed blocks instead of the entire file. The official rsync man page also documents pipelined file transfer and incremental recursion, which lets modern versions begin transferring before the entire tree has been scanned.
That design saves bytes, but a large tree still requires work:
- enumerate source paths and metadata;
- build and exchange file-list information;
- decide which files or attributes changed;
- read source data and any destination basis data needed for the transfer;
- create, write, rename, and timestamp destination entries; and
- verify reconstructed files.
For one large file, payload transfer often dominates. A million-file tree can spend more time enumerating paths, comparing metadata, and creating destination entries. Read why transferring thousands of small files is slow for the file-count model.
Start with a measurement baseline
First preview what rsync believes will change:
rsync -a --dry-run --itemize-changes source/ user@example.com:/data/destination/
Then run the real test with whole-transfer progress and statistics:
rsync -a --info=progress2 --stats source/ user@example.com:/data/destination/
The man page defines --dry-run as a non-changing trial and --itemize-changes as a per-item change summary. It defines --info=progress2 as whole-transfer progress and --stats as transfer statistics that show how the delta algorithm behaved.
Record these values for every test:
| Measurement | Why it matters |
|---|---|
| Time until the first payload moves | Separates scanning and setup from transfer time |
| Total files examined and transferred | Shows whether file-list work dominates |
| Literal and matched data | Shows whether delta transfer saves meaningful bytes |
| RTT, loss, and retransmissions | Exposes the WAN path rather than blaming rsync by default |
| Sender and receiver CPU | Finds SSH, checksum, compression, or single-core limits |
| Source read and destination write I/O | Finds storage and metadata limits |
| End-to-end wall time | Measures the job users actually wait for |
Do not compare only the progress-bar rate. A fast payload phase can hide a long scan or completion tail.
1. Avoid an unnecessary pre-transfer checksum scan
Do not add --checksum (-c) as a generic performance or safety setting. Rsync normally uses size and modification time for its quick check. With --checksum, both sides read file data to decide whether same-size files differ. The official man page warns that this can add substantial disk I/O before changed files are transferred.
Rsync separately verifies each transferred file as it reconstructs it at the receiver. That transfer verification is not the same as --checksum change detection.
Use --checksum only when the source of truth can change without a trustworthy size or modification-time difference. Benchmark the scan separately before enabling it for a large production tree.
2. Keep one session and one scoped file list
One recursive rsync command reuses its transport and pipelines work. A shell loop that starts a new rsync command for every file repeats SSH setup, process creation, file-list negotiation, and WAN latency.
If another system already knows the exact changed paths, --files-from can limit the scan. The rsync man page notes that sorting this list helps avoid revisiting shared path elements:
rsync -a -r --files-from=changed-files.txt source/ user@example.com:/data/destination/
With --files-from, -a does not imply recursion, so add -r when directory entries should recurse. Generate the list safely, test with --dry-run, and do not use an incomplete list for a workflow that must discover every change.
Modern rsync enables incremental recursion by default when both sides are version 3.0.0 or newer. Options such as --delete-before, --delete-after, --prune-empty-dirs, and --delay-updates require the full file list and disable that mode. Keep those semantics when the workflow requires them, but account for the longer pre-transfer scan instead of treating it as network slowness.
3. Test compression with the real data
--compress (-z) reduces bytes sent and can help on a constrained WAN with compressible text, logs, CSV, or source code. It also consumes CPU. JPEG, MP4, ZIP, and other compressed formats usually provide little additional reduction.
Test both modes with the same tree:
rsync -a --stats source/ user@example.com:/data/destination/
rsync -az --stats source/ user@example.com:/data/destination/
Current rsync versions negotiate a supported compression method such as zstd, lz4, or zlib when both sides support it. Check rsync --version on both endpoints before forcing an algorithm or level. The official man page also maintains a skip-compress suffix list for common already-compressed formats.
Keep compression when the reduction in transmitted bytes improves wall-clock time without saturating the sender. Turn it off when CPU rises and completion time does not improve.
4. Preserve partial data for interrupted transfers
For large files on an unreliable route, preserve a partial destination so the next run can use it:
rsync -a --partial --partial-dir=.rsync-partial source/ user@example.com:/data/destination/
Use a destination-controlled directory that is not writable by other users; the rsync documentation warns that an untrusted writable partial directory is a security risk. Also test the free-space requirement and cleanup behavior.
Partial-file reuse matters most for large interrupted files. It does not remove the metadata cost of thousands of tiny files, and it interacts with options such as --whole-file, --inplace, and delayed updates. Validate the exact command with non-production data.
5. Treat --whole-file as a test, not a universal fix
--whole-file (-W) disables rsync’s delta-transfer algorithm and sends each selected file in full. The man page says it can be faster when reading destination basis data is more expensive than sending the whole file, especially with networked storage. The trade-off is more WAN bytes.
Test it when:
- selected files are new or almost entirely changed;
- destination basis reads are slow;
- the WAN has spare capacity; and
- a controlled baseline shows delta calculation or basis I/O is the limit.
Do not use it blindly on a metered or constrained WAN, or where existing large files differ by only small regions. Compare literal bytes and wall-clock time in --stats.
6. Separate small-file and large-file bottlenecks
Use at least three runs:
- one large file to measure the streaming path;
- a representative folder with the real file count; and
- the same folder on a low-latency local path, when possible.
Interpret the result:
| Result | Likely limit | Next test |
|---|---|---|
| Large file and folder are both slow | WAN, SSH CPU, storage, or shaping | Compare iperf3, CPU, and local disk rates |
| Large file is fast; folder is slow | Enumeration, metadata, per-file work | Measure time to first payload and files per second |
| Local folder is also slow | Source or destination filesystem | Test metadata IOPS and background indexing |
| Compression helps text but not media | Bandwidth versus CPU/file type | Keep workload-specific profiles |
| Second run is much faster | Destination basis or cache matters | Report cold and warm runs separately |
A simple latency budget can explain the scale. If a 50,000-file workflow serialized one extra 80 ms WAN exchange per file, the waiting term alone would be 50,000 x 0.08 = 4,000 seconds, or 66 minutes 40 seconds. Real rsync pipelines work, so this is not a prediction; it shows why both file count and serialized RTT belong in the model.
Use the 1 TB transfer-time calculator for the payload-only lower bound and the long-distance file transfer guide for bandwidth-delay, direction, and loss tests.
When rsync is still the right tool
Keep rsync when you need its file-selection rules, POSIX metadata behavior, delta updates, scripts, or a standard remote-shell workflow and the measured completion time meets the objective. It is especially effective for repeated updates when most destination data is already correct.
Compare another transfer workflow when the operational requirement is different: very large first copies, folders dominated by tiny files, browser delivery to outside recipients, centrally managed cross-site sync, or resumable transfers without maintaining SSH access and rsync versions at both ends.
WarpSend does not implement rsync and is not a drop-in replacement for rsync flags, ownership semantics, hard links, or delete behavior. It is an alternative file-delivery workflow for supported endpoints. Use the same source, destination, route, and file set to compare it with rsync. Review WarpDirect, then start a free test only after the rsync baseline is recorded.
Primary sources and scope
The option behavior in this guide was checked on August 6, 2026 against the official rsync 3.4.4 man page and the project’s explanation of how rsync works. Adapt the commands to the dataset and required metadata before production use. Test deletion, permissions, links, sparse files, extended attributes, interruption, and restore behavior for the actual operating systems and filesystems before changing a production job.
Frequently asked questions
Why is rsync slow over a WAN?
Rsync over a WAN can be limited by directory scanning, per-file metadata work, round-trip latency, SSH CPU, destination storage, packet loss, or an unnecessary pre-transfer checksum scan. Measure scan time, changed-file count, RTT, loss, CPU, disk, and wall-clock completion before changing options.
Does rsync transfer many small files efficiently?
Rsync pipelines file transfers and modern versions use incremental recursion, but every file still requires filesystem and metadata work. A directory with thousands of small files can therefore be storage- or latency-bound even when the WAN has unused bandwidth.
Should I use rsync compression over the internet?
Test compression with the real file types. It can reduce bytes for compressible data on a constrained link, but consumes CPU and provides little benefit for formats such as JPEG, MP4, ZIP, and other already-compressed data. Modern rsync versions negotiate a supported compression method.
Should I add --checksum to make rsync safer?
Not by default. The --checksum option changes the pre-transfer decision and makes both sides read file data to decide what changed, which can add substantial disk I/O. Rsync already verifies each transferred file during reconstruction. Use --checksum only when size and modification time are not reliable enough for the change-detection requirement.