Updating a live directory with rsync normally replaces the receiver's previous file as soon as the transfer succeeds. A separate backup directory keeps that displaced copy available while the live destination advances to the new release.
The --backup-dir option stores overwritten files on the receiving side and also catches destination-only files removed by --delete. For a local sync, the receiver is the local machine; for an SSH push, it is the remote host that owns the destination path. Keep the rollback directory outside the live tree so it cannot be copied into or served with the release.
Use a fresh backup directory for every run that needs its own rollback point. Reusing the same directory can replace an earlier backup when the same relative path changes again. A dry run with itemized changes should show the overwrite and every deletion before the live command is allowed to modify the destination.
Source: /srv/release/ Live destination: /srv/www/ Rollback directory: /srv/rollback/2026-07-11/
The trailing slash on /srv/release/ copies the directory contents into /srv/www/. Use a unique timestamp or release identifier instead of reusing this sample date.
$ install -d -m 0750 /srv/rollback/2026-07-11
For an SSH push, create this path on the remote receiving host. An absolute path avoids the destination-relative behavior of a relative --backup-dir value.
$ rsync -ain --delete --backup-dir=/srv/rollback/2026-07-11 /srv/release/ /srv/www/ *deleting obsolete.html >f.st...... index.html >f+++++++++ notes.txt
--delete moves destination-only files into the rollback directory during the live run. Stop if a *deleting line names a file that should remain in the live tree.
$ rsync -ai --delete --backup-dir=/srv/rollback/2026-07-11 /srv/release/ /srv/www/ *deleting obsolete.html >f.st...... index.html >f+++++++++ notes.txt
$ ls -1 /srv/www index.html notes.txt
$ ls -1 /srv/rollback/2026-07-11 index.html obsolete.html
The overwritten index.html and deleted obsolete.html keep their destination-relative names because no backup suffix was set.
$ cat /srv/rollback/2026-07-11/index.html release 1
$ cat /srv/rollback/2026-07-11/obsolete.html retired page