About this article: AI-assisted writing, reviewed against the cited sources. This is source research, not lab validation. Check the stated versions and your own requirements before making changes.
A long-standing way to back up Linux servers and file shares is a set of dated directories on a backup disk, each looking like a complete copy of the source, built with rsync's --link-dest option or with rsnapshot, which wraps rsync. Seven daily snapshots and four weekly ones cost little more space than one copy plus the changes.
That works because the snapshots are not separate copies. Unchanged files are the same file on disk, reached through several names. Understanding that one fact explains how these backups save space, what deleting a snapshot really frees, why permission changes cost space, and why a mistake or an attacker on the backup host can affect every snapshot at once (our reading). This guide covers each in turn.
Why it matters
Hard-link snapshots are easy to set up and easy to restore from: a restore is a file copy from a directory. The risk is treating seven dated directories as seven independent backups. If they share one copy of each unchanged file, they share its fate (our reading). Knowing where the sharing begins and ends lets you decide what else you need, such as a second copy on separate storage.
How --link-dest works
The rsync manual (current for rsync 3.5.2) describes --link-dest=DIR: "This option behaves like --copy-dest , but unchanged files are hard linked from DIR to the destination directory." Its example is:
rsync -av --link-dest=$PWD/prior_dir host:src_dir/ new_dir/
The command is an illustrative isolated-test example, not a complete server-backup recipe. The archive option -a omits ACLs (-A), extended attributes (-X) and source hard-link relationships (-H), among other metadata. Choose preservation options for the actual data and confirm that both filesystem and permissions support them. Cross-snapshot linking from --link-dest is different from preserving hard links within the source tree with -H. Validate restores for the required attributes as well as file bytes.
Each run writes into a new, empty directory. Files unchanged since prior_dir become new names for the existing files; changed or new files are transferred and stored as new files.
What a hard link means comes from the Linux link(2) manual: "This new name may be used exactly as the old one for any operation; both names refer to the same file (and so have the same permissions and ownership)". The page adds that it is impossible to tell which name was the original. There is no master copy and no snapshot copy; there is one file with several names (our reading of that page).
rsnapshot's HOWTO describes the same idea for its rotation scheme: unless files change between snapshots, its full backups "are really just multiple hard links to the same files." When a file changes, "the next backup will unlink the hard link in hourly.0, and replace it with a brand new file."
When files do not link
The rsync manual is explicit: "The files must be identical in all preserved attributes (e.g. permissions, possibly ownership) in order for the files to be linked together." It continues: "If files aren't linking, double-check their attributes. Also check if some attributes are getting forced outside of rsync's control, such a mount option that squishes root to a single user, or mounts a removable drive with generic ownership".
Two practical consequences (our reading):
- A permission or ownership change at the source costs space. If someone changes the mode or owner of a large directory tree, the next snapshot cannot link those files to the previous one, and stores them again, even though the contents are identical. The manual adds: "If a match is found that differs only in attributes, a local copy is made and the attributes updated."
- A destination that cannot preserve ownership (for example a network share that maps every file to one user) can stop linking for every file, so each snapshot becomes a full copy until the disk fills.
The manual also notes that "A --link-dest on another filesystem is fine: only the link to DIR is impossible there". Hard links cannot cross filesystems; the link(2) manual lists the error "EXDEV oldpath and newpath are not on the same mounted filesystem." If the previous snapshot sits on a different filesystem from the new one, unchanged files cannot be linked to it (our reading).
Other caveats from the manual: this option "works best when copying into an empty destination hierarchy, as existing files may get their attributes tweaked, and that can affect alternate destination files via hard-links"; and combined with --ignore-times, "rsync will not link any files together".
The one option to keep away from snapshots: --inplace
By default rsync writes a changed file as a new file and moves it into place. The manual's --inplace entry warns that with this option, "Hard links are not broken. This means the new data will be visible through other hard links to the destination file."
Used against a snapshot set, that would mean new data written into a file that older snapshots share, changing those older snapshots as well (our reading). Check any snapshot script or configuration for --inplace and treat its presence as a defect.
Rotation and deletion
rsnapshot rotates directories such as hourly.0 to hourly.5 and daily.0 to daily.6. Its HOWTO explains: running the hourly job will "rotate the hourly.X directories", then copy the contents of hourly.0 into hourly.1 using hard links. The daily job will "rotate all the daily.X directories, then copy the contents of hourly.5 into daily.0." It notes that the order of interval lines in the configuration matters, with the smallest first.
Deleting the oldest snapshot removes one name from each file in it. The inode(7) manual describes the link count field: "This field contains the number of hard links to the file." Space is freed only for files whose last name was in that snapshot; files still named in newer snapshots stay on disk (our understanding of how Linux filesystems release space). So removing a snapshot may free very little, and freeing space may require removing several (our reading).
What --delete does here
The rsync manual says --delete "tells rsync to delete extraneous files from the receiving side (those that don't exist on the sending side), but only for the directories that are being synchronized." With --link-dest into a new empty directory, a file deleted at the source is simply not linked into the new snapshot; it remains in older snapshots until they rotate out (our reading). If a script instead re-uses an existing snapshot directory with --delete, names disappear from that snapshot only, while other snapshots keep theirs (our reading). A version remains recoverable while any retained snapshot still names it, including a newer surviving snapshot. It ceases to be available from the snapshot set only when its last retained reference is removed. Removing a directory entry and reclaiming storage are different events; other links and open handles can keep the underlying file allocated.
Why these snapshots are not immutable
Every name refers to the same file with "the same permissions and ownership". Anyone who can write to that file through one snapshot changes it in all of them (our reading of link(2)).
rsnapshot's HOWTO addresses access directly. It says rsnapshot creates the snapshot root with permissions 700, "and for good reason", because "if they can see the snapshots directly, they can modify them, and the integrity of the snapshots can not be guaranteed." Its example: "if a user had write permission to the backups and accidentally ran rm -rf /, they would delete all their files in their home directory and all the files they owned in the backups!" Its suggested answer for user self-service is to keep the real snapshot root private and mount it "for the users read-only", for example over NFS.
That protects against ordinary users. It does not protect against root on the backup host, which can delete or alter any snapshot (our reading). The Australian Signals Directorate's ISM includes control ISM-2151: "Backups are stored using a technically enforced immutability mechanism that prevents their modification or deletion for the duration of their retention period." File permissions on a backup disk are not that mechanism (our reading). If you rely on hard-link snapshots, a second copy on storage that the backup host's administrators cannot alter or delete is the usual way to close the gap (our recommendation).
One file, every snapshot
Because unchanged files are stored once, damage to that stored file, from a disk fault or an accidental write, appears in every snapshot that names it (our reading). The snapshots give you history of changes at the source; they do not give you redundant copies of unchanged data.
Read-only checks
These commands read metadata and change nothing. Run them in Bash as a user with read access to the snapshots, preferably against a read-only mount. Keep the output and any permission errors.
Is a file shared across snapshots?
stat -c '%d %h %i %n' /snapshots/daily.0/path/to/file /snapshots/daily.6/path/to/file
In stat(1), %d is the device number, %h the hard-link count, %i the inode number and %n the file name. Matching device and inode values in this local filesystem view identify the same underlying file; matching inode numbers on different devices do not. A link count of 1 on a file you expected to be shared suggests linking is not happening.
How much space does each snapshot really add?
du -sh /snapshots/daily.0 /snapshots/daily.1
The du(1) manual describes -l, --count-links as "count sizes many times if hard linked", which implies the default counts each linked file once per run (our understanding of GNU du). Listing several snapshots in one command therefore shows the first in full and the rest as what each adds. rsnapshot's HOWTO notes that it uses du because space use is "otherwise difficult to estimate because of all the hard links."
Which selected source files and archive attributes differ?
rsync -a -n -i --checksum /source/path/ /snapshots/daily.0/path/
The manual describes --dry-run as "a trial run that doesn't make any changes", and --itemize-changes as "a simple itemized list of the changes that are being made to each file, including attribute changes." With --checksum, rsync compares file contents and "both sides will expend a lot of disk I/O reading all the data in the files". Run this only against a read-only mount of the snapshot, so that a mistyped command without -n cannot write into files shared by older snapshots (our recommendation). Differences can be legitimate changes since the snapshot was taken. This is a partial comparison: -a omits ACLs, extended attributes and source hard-link preservation, and without --delete it does not enumerate destination-only files. Keep the destination read-only, match the comparison options to the intended capture policy, and separately audit destination-only objects. A quiet dry run is neither whole-tree equality nor a successful application restore.
Is --inplace anywhere in the backup job? Read the script or rsnapshot.conf (for example with grep -n inplace on the file) and the rsync arguments it passes.
These checks show linking, space use and differences from the source. They do not show whether the stored data is undamaged since it was written, or whether anyone with root access has altered it (our reading).
Safe restore rehearsal
Run this on a test machine with synthetic data, in an authorised, isolated environment (our recommendation).
- Create test data: a directory of sample files of known content, plus one large file. Record SHA-256 hashes with
sha256sum. - Take three snapshots with your normal script or rsnapshot configuration into a test backup disk, changing one small file between each.
- Check linking with the
statandducommands above. Unchanged files should share an inode across snapshots. - Change permissions on the large file only, take another snapshot, and observe that it is stored again.
- Delete the oldest snapshot and measure how much space is freed.
- Restore a file from each snapshot to a separate scratch directory and compare hashes with the originals.
- Test protection: as an ordinary test user, try to read and modify the snapshot root, and record what is refused.
Diagnosing what you find
- Every snapshot is a full copy: attributes not preserved at the destination; ownership squashed by a mount or share option; the previous snapshot on a different filesystem;
--ignore-timesin use; or the--link-destpath wrong, which the manual notes is relative to the destination directory if not absolute. - A restored file differs from its hash in every snapshot: the stored file was damaged after it was written; the file was modified through a shared link (for example by
--inplaceor a direct edit); or the source was already wrong when first captured, in which case no snapshot holds a correct copy. - Deleting a snapshot frees little space: most of its files are still named by newer snapshots.
- Users can change snapshot contents: snapshot root permissions too open, or snapshots exposed read-write over a share.
Have a qualified person review the procedure before changing a production backup job.
Worked example (illustrative)
The following is invented. A small firm backs up its Linux file server nightly to a USB disk with rsnapshot, keeping seven daily and four weekly snapshots. One week the disk fills.
stat shows that files in the newest snapshot have different device/inode pairs from the preceding snapshot. A staff member had reset group ownership across the source share, so the first snapshot after that change had to store those files again even though their contents were unchanged. If the attributes then stabilise, later snapshots can link to that new copy; one ownership reset alone does not explain repeated full copies. The administrator measures actual unique storage and follows the agreed retention policy before removing any snapshot. Older snapshots can free little space while other retained snapshots still name their files.
While reviewing the job, they also note that the backup host's administrator account could delete every snapshot. They add a second copy to separate storage that the backup host cannot modify, and record both copies in the firm's recovery inventory.
Risks and limits
- Hard-link snapshots store unchanged data once. They are history, not redundancy.
- Root on the backup host can alter or delete every snapshot. Plan a separate, protected copy.
- The rsnapshot HOWTO is dated 2004; check your installed version's documentation for current options.
- The
duand inode behaviour described is our understanding of GNU du and common Linux filesystems; confirm on yours. - No command in this guide was run in a lab. Test every step in an isolated environment first.
Sources
All accessed 14 November 2026.
- rsync(1) manual page (current for rsync 3.5.2): https://download.samba.org/pub/rsync/rsync.1
- rsnapshot HOWTO: https://rsnapshot.org/rsnapshot/docs/docbook/rest.html
- rsnapshot README: https://raw.githubusercontent.com/rsnapshot/rsnapshot/master/README.md
- link(2) Linux manual page: https://man7.org/linux/man-pages/man2/link.2.html
- inode(7) Linux manual page: https://man7.org/linux/man-pages/man7/inode.7.html
- stat(1) Linux manual page: https://man7.org/linux/man-pages/man1/stat.1.html
- du(1) Linux manual page: https://man7.org/linux/man-pages/man1/du.1.html
- Australian Signals Directorate, Guidelines for system management (ISM, September 2026): https://www.cyber.gov.au/business-government/asds-cyber-security-frameworks/ism/cyber-security-guidelines/guidelines-for-system-management
Related future topics
- Adding a protected second copy to a hard-link snapshot scheme
- Checking a long-lived backup disk for silent damage
- Read-only self-service restores for staff over NFS or SMB
This article was originally published on .