Payments are experiencing issues due to temporary restrictions in Russia. If your payment does not go through, please submit a support request.Our support team is available 24/7 — we are always here to help with hosting and server issues.We are now accepting requests for dedicated server rental and colocation services in our data center.Reminder: we recommend enabling backups for additional data protection.A new VPS/VDS lineup with NVMe storage and improved performance is now available.Maintenance work on some servers has been completed. All services are operating normally.
Article6 min readViews0

rsync --dry-run: How to See Deletions and Overwrites Before Synchronization

A practical guide to safely checking rsync: read the itemized output, spot deleted files, and detect content changes when size and timestamp are identical.

Comments 0

Two storage drives connected by a cable next to two file drawers before synchronization verification
In this article

Before synchronizing with deletion, first run the same rsync command with --dry-run and --itemize-changes. Check the direction, the trailing slash on the source, and every line starting with *deleting. Only then decide if a real run is acceptable. A dry run does not replace a backup or application verification.

First, we test on a small model. The source and destination contain an identical file, a file with a different length, a new file, and an extra file. Another file has different content but the same size and modification time—this is exactly the case that reveals the limit of a standard fast rsync check.

Input Conditions and Boundaries

  • Linux with rsync 3.2.7, protocol 31; local model verified on October 17, 2026.

  • Source and destination are separate temporary directories. Working files, services, and network were not used.

  • The --delete flag was intentionally enabled: the material demonstrates how to view deletions before the actual run.

  • Remote SSH server, ACLs, extended attributes, sparse files, and open databases were not verified in the staging environment.

rsync --version

In the tested environment, the command showed rsync version 3.2.7 and protocol version 31. For remote synchronization, check the version on both sides: the set of options and the diagnostic format depend on the actual binary files running.

Why a Trailing Slash Changes the Result

The source source/ denotes the contents of the source directory, while source without a trailing slash denotes the source directory itself. With the wrong variant, files may end up at an additional nesting level. A dry-run will show the names, but the error can only be spotted if the expected destination tree has been recorded in advance.

rsync -ani --delete /path/source/ /path/destination/

Here, -a enables archive mode, -n prohibits changes, -i outputs a brief description of each action, and --delete adds removal of destination objects that do not exist in the source to the plan. The command remains dangerous after removing -n, so the direction and filters must be checked before running.

The semantics of options and the trailing slash were cross-checked against the official rsync guide. The documentation separately warns to use dry-run before --delete.

Source and destination before rsync: identical file, size and content changes, new and extra files
Training set. changed-hidden.txt differs in content but has the same 5 bytes and identical modification time.

What a standard dry-run showed

rsync -ani --delete "$src/" "$dst/"

*deleting stale.txt >f.s....... changed-size.txt >f+++++++++ new.txt

The destination remained unchanged: the list of names and the SHA-256 hash of each file before and after the dry-run matched. However, changed-hidden.txt is absent from the output. By default, rsync uses a fast size and modification time check; identical values can hide differing content.

Line

What we observe

What to check

*deleting stale.txt

File exists only in the destination and is included in the deletion plan

Is it needed, is it protected by a filter, and was the direction selected correctly

>f+++++++++ new.txt

A new regular file will be created in the destination

Are the path and nesting level expected?

>f.s....... changed-size.txt

The file will be transferred; the size differs

Is the change an incomplete write or from a random source?

No line for changed-hidden.txt

A quick check considered the file unchanged

Is content verification via --checksum necessary?

When --checksum is needed

If file size and mtime cannot be considered reliable indicators—for example, if files are restored with their original timestamps or generated with identical lengths—add --checksum. In this case, rsync reads the contents of files on both sides for a preliminary comparison. This increases disk I/O and verification time, especially on large directory trees.

rsync -anic --delete "$src/" "$dst/"

*deleting stale.txt >fc........ changed-hidden.txt >fcs....... changed-size.txt >f+++++++++ new.txt

In the >fc........ string, the letter c indicates a change in the content checksum. changed-hidden.txt was detected even though its length and mtime matched. This does not prove consistency between the database and application files: rsync compares available objects, not business transactions.

Reproducible test

The scenario created two temporary directories. For changed-hidden.txt, the source contained BBBB and the destination AAAA; both files were 5 bytes long with identical mtime. Before the actual run, the destination hashes were saved and recalculated after a standard dry-run.

printf 'BBBB\n' >"$src/changed-hidden.txt" printf 'AAAA\n' >"$dst/changed-hidden.txt" touch -t 202601010101 "$src/changed-hidden.txt" "$dst/changed-hidden.txt"

A standard dry-run completed with exit code 0 and did not modify any files, yet it failed to reveal the hidden discrepancy. A dry-run with --checksum showed four actions. Then, a real rsync was executed in the same isolated model using the same options without -n.

rsync -aic --delete "$src/" "$dst/"

The itemized output of the actual run matched the checksum dry-run verbatim. changed-size.txt and changed-hidden.txt were updated, new.txt appeared, and stale.txt disappeared. A subsequent dry-run with --checksum returned empty output and exit code 0.

rsync -anic --delete "$src/" "$dst/" printf 'exit=%s\n' "$?"

exit=0

Stage

Code

Observation

Destination change

Standard dry-run

0

Three actions; hidden change not found

No

Dry-run with --checksum

0

Four actions, including changed-hidden.txt

No

Actual run

0

Output matched the checksum dry-run

Yes, only in the test catalog

Final checksum dry-run

0

Empty output

No

Four stages of rsync verification: standard dry-run, dry-run with checksum, actual run, and final check with no changes.
Observed rsync 3.2.7 protocol: checksum revealed a hidden change; actual output matched the preliminary one, and the final dry-run was empty.

Order before working synchronization

  1. Record the source, destination, transfer direction, user, and rsync versions on both sides.

  2. Check the trailing slash and expected nesting level on a small, known subtree.

  3. Run the dry-run with the same include, exclude, and delete options planned for the actual run.

  4. Review each line of *deleting; if in doubt, stop and save the necessary data independently.

  5. Decide whether size and mtime are sufficient. If not, assess the load and run a dry-run with --checksum.

  6. Before making changes, ensure a consistent backup or another verified rollback method is in place.

  7. Execute the actual run without -n during a coordinated window and save the exit code and itemized output.

  8. Repeat the dry-run and verify not only the empty rsync plan but also application functionality and data integrity.

If the task involves an online store backup, separately verify RPO, RTO, and test restoration: an empty rsync output does not prove the backup is suitable for recovery.

Where dry-run offers no guarantee

  • The source or destination changed between the preliminary and actual runs.

  • The actual run encountered a read, write, space, network, or permission error that was not present during the check.

  • The open database was being written during the copy, so individual files correspond to different points in time.

  • Filters protect or exclude objects differently than expected; rules should be checked carefully, especially when used together with --delete.

  • ACLs, extended attributes, hard links, sparse files, or owners are required, but the corresponding options are not enabled or verified.

Do not consider code 0 an early success. Acceptance consists of three independent indicators: the preliminary plan is clear, the actual run completed without unexplained actions, and the result is verified by the application's original operation or restoration.

Discussion 0

Share your experience and ask questions. Comments without links appear after editorial review.

No comments yet. Start the discussion.