Build rsync commands for backups, mirrors and migrations - archive mode, SSH, delete modes, filters and a dry run. Free, runs in your browser.
rsync is the standard tool for copying and synchronising files on Linux, macOS and BSD. What makes it different from cp or scp is the delta-transfer algorithm: on the second and every later run it sends only the parts of files that actually changed, which is why it is the backbone of most backup, mirror and server-migration workflows. This builder assembles the command for you, explains what each flag does, and flags the combinations that destroy data.
This is the single most common rsync mistake, and it is worth understanding before anything else. The trailing slash on the source changes the meaning of the command:
| Command | Result |
|---|---|
rsync -a /src /dest | Creates /dest/src/ and copies the contents into it |
rsync -a /src/ /dest | Copies the contents of /src directly into /dest |
The destination trailing slash makes no difference. Only the source one matters. Running the first form when you meant the second is how people end up with /backup/backup/backup nested directories.
-a (archive) is the flag almost every rsync command starts with. It is shorthand for -rlptgoD: recursive, preserve symlinks, permissions, modification times, group, owner and device/special files. It is what you want for a backup or a migration.
What -a does not include catches people out. ACLs need -A, extended attributes need -X, and hard links need -H - all three are separate flags, and all three matter when you are migrating a server. Preserving ownership also requires running as root on the receiving side; without it, everything lands owned by the connecting user.
By default rsync only adds and updates - it never removes anything. To make the destination an exact mirror you need a delete option, and this is where data gets lost:
| Option | When files are deleted |
|---|---|
--delete-during | As the transfer proceeds. The default, and the lightest on memory. |
--delete-before | Before transferring. Use when the destination is short on free space. |
--delete-after | Once everything has transferred. Safest for a live site - nothing disappears until the new copy is in place. |
--delete-excluded | Also removes files your exclude rules were protecting. Rarely what you want. |
The classic disaster is a delete-enabled sync where the source failed to mount. Rsync sees an empty source tree, concludes every destination file is extraneous, and removes all of them. --max-delete=N aborts the run if it would delete more than N files, and costs nothing to add.
Filter rules are evaluated in order and the first match wins. That ordering is why an --include on its own does nothing - rsync already includes everything by default, so there is nothing for the include to rescue. Includes only become meaningful when a later exclude would otherwise catch the file.
To transfer only certain files, the pattern is: include what you want, include */ so rsync is allowed to descend into directories, then exclude * last.
By default rsync decides whether to transfer a file by comparing size and modification time - fast, and correct almost all of the time. The alternatives trade speed for certainty. -c reads and checksums every file on both ends before deciding, which is thorough but expensive on a large tree. --size-only ignores timestamps entirely, useful when a migration has rewritten every mtime. -u skips files that are newer at the destination.
--partial keeps partially transferred files so a re-run can pick up where it left off, and --partial-dir puts them somewhere tidy instead of leaving fragments in the destination tree. --append and --append-verify go further and only ever grow existing files - fast for genuinely append-only data such as logs, but silently corrupting if the earlier part of the source file changed.
Rsync returns 0 on success. In scripts, the two worth special-casing are 23 and 24: they mean some files were skipped or vanished during the run, which happens routinely on a live system and is usually harmless. 30 is a timeout, 12 a protocol error, and 255 an SSH failure rather than an rsync one.
They solve the same problem on different platforms. Rsync is the Unix answer and excels at synchronising over a network, because it only sends changed blocks. Robocopy is the Windows equivalent, better integrated with NTFS permissions and Windows scheduling. If you are copying between Windows servers, use robocopy; between Linux hosts, or over a slow WAN link, use rsync.