Independent comparison · no paid rankings
Home / Blog / Technical / rsync: options that prevent a destructive synchronization

rsync: options that prevent a destructive synchronization

A reversed rsync cron wipes prod: trailing slash, --delete, and written SRC→DST direction prevent destructive sync.

Hébergeurs.eu Editorial Team 4 min read Updated Jul 19, 2026

Friday evening the team refreshes staging: rsync prod → staging with --delete to mirror production exactly. Monday morning staging is correct — but production shows missing files. A mis-commented cron reversed direction: staging to prod. rsync wiped production to match partially empty staging.

rsync is the go-to tool for fast mirrors and file-based deploys. It is also symmetric in danger: the same flags that sync cleanly can destroy years of files in one command. Trailing slash, --delete, SRC→DST direction, and excludes are not details — they are the line between a healthy refresh and a P1 incident.

Trailing slash: the rule to tattoo


rsync -av prod:/var/www/ staging:/var/www/

# copies CONTENTS of /var/www/



rsync -av prod:/var/www staging:/var/www/

# creates staging:/var/www/www — nested nesting

With trailing slash on source, rsync copies directory contents. Without slash, it copies the directory itself into destination. The www/www mistake is a staging refresh classic.

Document convention in every script: comment # SRC=prod:/var/www/ DST=staging:/var/www/ with explicit arrows.

--dry-run and --delete

Always -n or --dry-run before any sync with --delete. Then --itemize-changes for readable audit. Any *deleting line in output = mandatory pause, direction re-read, dated backup.

--delete removes on destination what no longer exists on source. Acceptable only after validated dry-run, dated destination backup, written direction, two-person review.

Never --delete on cron without exit code monitoring and mail alert on non-zero.

Direction, flock, and backup-dir

NeedSafe pattern
Staging refreshprod → staging, delete staging only
DR mirrorprod → DR, periodic checksum -c
DeployCI artifact, not full prod rsync

flock on cron prevents overlapping syncs. --backup --backup-dir=dated/ before mass delete — saves timestamped copy of removed files.

Explicit RSYNC_RSH=ssh; harmonize GNU vs BSD rsync versions across servers before automation.

Excludes and pitfalls

Git-versioned --exclude-from file: .env, storage/sessions, uploads, runtime caches, node_modules. Never sync cache to prod nor unsanitized secrets to staging.

--delete-excluded is extremely dangerous — avoid except documented expert cases.

rsync also propagates ransomware: rsync mirror alone is not backup strategy. Pair immutable restic or Borg for history; rsync for mirror speed.

Monitoring and training

Alias rsync-safe='rsync -av --dry-run --itemize-changes' for all ops. Removing dry-run = conscious signed act.

Post-sync: script diff file count source/destination. Cron mail on non-zero exit — silent fail classic Friday night.

30-minute onboarding: trailing slash quiz, reversed direction post-mortem reading. Two crons opposite directions = eventual data loss — mandatory architecture review.

Pair with versioning

Rsync mirror for speed, restic or Borg for history — document which is source of truth for restore. Never tell auditor rsync alone is backup strategy.

Bi-directional rsync two cron jobs opposite direction equals data loss eventually — architecture review any bidirectional sync.

File ownership numeric IDs differ across servers — rsync -a preserves, breaks if www-data UID differs.

Operational follow-up

Rsync ops onboarding training — 30 minutes prevents weekend incident. Trailing slash quiz exercise. Cron mail on rsync non-zero exit — silent fail classic Friday night. Document gaps between host marketing and field measurement in the quarterly review.

Quarterly follow-up

Rsync ops onboarding training — 30 minutes prevents weekend incident. Trailing slash quiz exercise. Cron mail on rsync non-zero exit — silent fail classic Friday night. Document gaps between host marketing and field measurement in the quarterly review.

Post-sync file count diff script catches partial transfers before users notice missing assets.

Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.

Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.

Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.

Decide and move forward without blind spots

  1. rsync-safe alias with --dry-run — removing dry-run = conscious signed act.
  2. Tattoo trailing slash — SRC with / copies contents; without / creates nested nesting.
  3. SRC → DST direction in comment — every cron script; flock against overlap.
  4. Git-versioned excludes — .env, sessions, uploads; never --delete-excluded without review.
  5. Pair rsync mirror + immutable versioned backup — rsync alone propagates ransomware.

Deploy and DR: guides, directory, comparison tool.

Frequently asked questions

What does trailing slash on source change?

With /: rsync copies directory contents. Without /: nested subdirectory — classic staging/www/www mistake.

When is --delete acceptable?

After validated dry-run, dated backup, written SRC→DST, two-person review. Never on cron without exit code monitoring.

Should cache and node_modules be excluded?

Yes via versioned --exclude-from. Do not sync runtime cache to prod nor .env or sessions.

Does rsync replace versioned backup?

No: rsync also propagates ransomware. Pair immutable backup (restic, Borg) with rsync mirror.


Default aliases to --dry-run — removing it must be a conscious act.

Compare European hosts

Filter by compliance, location and use case — then open the sheets to verify the real scope.

Browse the directory
Blog

Related reading

All articles →