Automating the snapshot pattern from episode 8 into a daily/weekly/monthly rotation system with --link-dest, writing rotation and old-snapshot cleanup scripts, and applying the best practice of consistent --delete and --delete-excluded across snapshots.

Episode 8 gave you the single snapshot pattern. Episode 9 completes the system: how those snapshots are arranged into a regular rotation — daily, weekly, monthly — then cleaned up automatically without damaging the others. This is the backup shape you want on a production server: runs by itself, doesn't burden the team, and has an explainable history.
The key to trusting this system: because every snapshot uses --link-dest, deleting an old snapshot never damages a newer one — shared files stay intact as long as at least one snapshot still references them.
The classic rotation strategy is called grandfather-father-son:
The result: you can go back to yesterday, last week, or last month — with about 23 snapshot directories in total, not 365.
A daily backup script with --link-dest references the previous snapshot:
#!/bin/bash
SOURCE=/home/data
BACKUP=/backup
LAST=$(ls -1d $BACKUP/backup-* 2>/dev/null | tail -1)
rsync -a --delete \
${LAST:+--link-dest="$LAST"} \
"$SOURCE/" "$BACKUP/backup-$(date +%Y-%m-%d)/"${LAST:+--link-dest="$LAST"} adds --link-dest only if a previous snapshot exists — day one naturally becomes a full backup. The result each day: backup-2026-08-12, backup-2026-08-13, and so on.
Tip
A simpler, widely used alternative: the newest snapshot is current, and each day current is first rolled into a date-stamped snapshot. This avoids name splitting and makes "today's snapshot" always easy to access.
Deleting old snapshots is safe thanks to hardlinks: files referenced by other snapshots stay alive — only the name disappears. A cleanup script:
find /backup -maxdepth 1 -type d -name 'backup-*' -mtime +7 -exec rm -rf {} +Important: use plain rm -rf, not other deletion tools, so hardlinks are broken correctly — only snapshots that truly no longer reference a file have their space freed. This is why hardlink-based rotation is much safer than chained incremental systems.
One detail that's often forgotten: to keep consistency across snapshots, every snapshot must be built from the same state. The rules:
--delete — if the source deletes a file, the next snapshot must also record that deletion; without --delete, snapshots accumulate "ghosts" of files that no longer exist.--delete-excluded — if files are excluded (episode 6), decide once: whether excluded files in old snapshots are also deleted (--delete-excluded) or left alone. Don't change it between snapshots.Because every snapshot is built with --link-dest to the previous one, inconsistent rules make the hardlink chain suboptimal — files that should be unchanged get treated as changed because of differing filter rules.
rsync -a --delete --delete-excluded \
--exclude-from=/etc/rsync-backup.excludes \
${LAST:+--link-dest="$LAST"} \
"$SOURCE/" "$BACKUP/backup-$(date +%Y-%m-%d)/"Important
Pick one set of rules (delete + exclude) and lock it in the same script every day. Changing the rules in the middle of snapshot history makes one snapshot contain "differences" that aren't real data changes — and consumes extra space for no reason.
--link-dest path — remember, it's relative to the destination directory, not where you run rsync. --link-dest=../backup-1/ from /backup/backup-2/ refers to /backup/backup-1/.ls -1d or sort dates, not plain ls, which sorts lexically (backup-2026-08-09 before backup-2026-08-10).find -exec deletion — always -exec rm -rf {} + (or the safer \; for paths with spaces).stat (episode 8).The script above is ready to be scheduled — and that's the bridge to episode 10:
30 2 * * * /usr/local/bin/snapshot-daily.sh >> /var/log/rsync.log 2>&1We'll dissect full cron automation, exit codes, and notifications in episode 10. What matters now: this rotation script runs by itself, the snapshots are clean and consistent, and disk space stays under control.
In this episode you've built a self-sufficient snapshot rotation system.
Key takeaways:
--link-dest to the previous snapshot; day one becomes a full backup automatically.rm -rf — hardlinks ensure the others aren't damaged.--delete/--delete-excluded rules so they're consistent across snapshots.--link-dest paths relative to the destination, sorting date names, filesystems without hardlinks.In episode 10 we fully automate: automation with cron — scheduling rsync via crontab, directing logs to a file (>> /var/log/rsync.log 2>&1), understanding rsync exit codes (0 success, 23 partial), email notifications, and lock files to prevent overlaps. See you in episode 10!