If you have ever deleted a file on your Mac and watched your free space stay exactly the same, a hard link is a likely explanation. A hard link is not a shortcut and not a copy. It is a second name, in the filesystem's directory structure, pointing at the same underlying data as the first name. Delete one name and the data is still there, reachable through the other name, using exactly as much disk space as before. This article explains what a hard link actually is, how to see how many names point at a given file, how to track them all down, and why Time Machine has depended on this mechanism for years.
What a hard link actually is
Every file on an APFS or HFS+ volume is really two things: an inode and one or more directory entries. The inode holds the file's metadata and a pointer to its data blocks. The directory entry is just a name in a folder that references an inode number. When you create a file normally, macOS creates one inode and one directory entry pointing at it. A hard link adds a second directory entry, possibly in a different folder with a different name, that points at the same inode.
Nothing about the file's content is duplicated. Both names refer to identical data, and there is no way to tell, by opening either one, which is the "original" and which is the "link" — that distinction doesn't exist at the filesystem level. It's a subtle but important difference from an alias or a symlink, both of which are separate objects that merely reference a path.
Seeing the link count with ls -l
The filesystem keeps a count of how many directory entries point at each inode. You can see it with the standard long-listing form of ls:
ls -l somefile.txt
-rw-r--r-- 3 deepak staff 1024 Aug 6 10:02 somefile.txt
The number immediately after the permissions bits — 3 in this example — is the link count. For an ordinary file with no hard links, this is 1. A value of 3 means three directory entries, somewhere on the volume, point at this exact inode. ls -l does not tell you where the other two are; it only tells you that they exist.
For a directory, this number means something slightly different (it reflects internal structure, not user-visible links), so this trick is really about ordinary files.
Finding every name that points at the same inode
Once you know a file has a link count greater than one, the next question is naturally: where are the other names? The standard tool for this is find, using its -samefile test:
find ~/Projects -samefile ~/Projects/report-final.txt
This walks the given directory tree and prints every path whose inode matches the inode of report-final.txt — including report-final.txt itself. If the link count from ls -l was 3, you should expect three results, assuming all of them live under the folder you searched. If some live outside that folder, you will need to point find at a wider starting path, up to the whole volume, to catch them all.
This is the only reliable way to find hard-linked names, because there is no metadata on the file itself that lists them. The inode does not know its own directory entries; the relationship only exists from the directory side.
Why Time Machine relied on hard links
Time Machine's backup design, going back to its original implementation on HFS+, needed a way to look like it stored a complete, independent snapshot of your disk every hour, without actually copying every file every hour. Hard links solved this elegantly. When a file had not changed since the last backup, the new backup folder would simply add a hard link to the exact same inode already stored in the previous backup. Only files that had genuinely changed were copied fresh.
The result, from the user's point of view, was that each hourly backup folder looked like a full copy of the entire disk — you could browse into any one of them and see everything, in the state it was in at that time. Underneath, unchanged files were not duplicated at all; the same inode was referenced by dozens of backup folders simultaneously, and the space cost of "another backup" was mostly just the changed files plus a small amount of directory-entry overhead.
How APFS clones changed this
When Apple moved Time Machine onto APFS-formatted backup destinations, the mechanism shifted from hard links to APFS's native copy-on-write clone files. A clone is conceptually similar in spirit — it lets two file references share the same underlying data blocks without duplicating them — but it works below the directory-entry layer, using the filesystem's copy-on-write machinery, rather than through the older hard-link-count model. The practical effect for users is the same: unchanged data between backups doesn't consume additional space, and it is copied only once a difference is actually written. Whether a given backup destination uses hard links or clones depends on the filesystem it is formatted with; APFS-based Time Machine backups use the newer clone mechanism.
Why deleting one hard-linked name never frees space by itself
This is the detail that catches people out. If ls -l reports a link count of 3 for a file and you delete one of the three names, the inode's link count simply drops to 2. The data is still fully intact and still occupying exactly the same disk blocks, because two other directory entries still reference it. Space is only reclaimed once the link count reaches zero — meaning every single directory entry that pointed at that inode has been removed, and nothing else (including an open file handle held by a running process) still references it.
This is worth remembering whenever a storage tool reports "duplicate" files that turn out to be hard links of one another: deleting the apparent duplicate does not recover the space you think it will, because there was only ever one copy of the data to begin with.
Conclusion
Hard links are a small, old idea — a directory is just a list of names pointing at inodes, and nothing stops two names from pointing at the same one — but they explain a surprising number of things that otherwise look like bugs: backups that seem impossibly efficient, files that don't shrink your free space when deleted, and size totals that don't add up the way you'd expect from a simple file listing.
We built VolumeLens to get this right rather than gloss over it. When it scans a volume, it recognises hard-linked files and counts their data once, not once per name, so a folder full of Time-Machine-style hard links doesn't inflate the total you see. If you're curious how it handles other filesystem details like this, the features page has more on what it checks for before it shows you a number.