Symbolic Link vs Hard Link: What Is the Difference?
A symlink stores a path and can break; a hard link is a second real name for the same file.
Side by side
| symbolic link | hard link | |
|---|---|---|
| What it stores | A path, resolved on every access | A direct reference to the inode |
| Cross filesystems | Yes | No — inode numbers are per-filesystem |
| Point to directories | Yes | No (would allow loops in the tree) |
| Breaks if target moves | Yes, becomes a dangling link | No — there is no "target" to move |
| Point to something not yet created | Yes | No |
| Visible in ls -l | Yes: link -> /the/target | Indistinguishable from a normal file |
| Deleting the original | Link breaks | Data survives in the other name |
| Disk space used | A few bytes for the path | Just a directory entry |
| Command | ln -s target link | ln target link |
Which one, when
Switching between deployed releases
Use symlink
The classic pattern: /opt/app/current points at the active release, and deploying is one atomic link change. Rolling back is pointing it back.
$ ln -sfn /opt/app/releases/2026-08-10 /opt/app/current Keeping dotfiles in a git repo
Use symlink
The real files live in the repo, links put them where programs expect. git pull updates every machine at once.
$ ln -s ~/dotfiles/.vimrc ~/.vimrc Deduplicating identical files in a backup
Use hard link
Two names, one copy of the data, no wasted space — and neither name is more "real" than the other, so pruning either is safe.
$ cp -al backup-monday/ backup-tuesday/ Putting a tool on your PATH
Use symlink
Link the binary into a directory already on PATH. Updating the tool updates the link's destination automatically.
$ ln -s /opt/tool/bin/tool ~/.local/bin/tool Making a file survive its original name being deleted
Use hard link
The data lives until the last name is removed. With a symlink you would be left holding a broken pointer.
$ ln important.log important.log.keep Gotchas worth knowing
- Argument order is target first, link name second — the same order as cp. Getting it backwards creates a link in the wrong place named after your target.
- Updating a symlink that points at a directory needs -n: `ln -sfn newtarget link`. Without it, the new link is created INSIDE the old target.
- Relative symlinks break when the link is moved. Prefer absolute targets for anything scripts depend on.
- Find broken symlinks with `find -L dir -type l` — a useful health check after big moves or restores.
- Hard links to the same file share permissions and ownership, because there is only one inode. Changing them through one name changes them for all.
Frequently asked questions
How do I tell if a file is a symlink?
ls -l shows an l as the first character and prints "name -> target". A hard link is indistinguishable from a normal file; only the link count in column 2 hints at it.
Does deleting a symlink delete the target?
No. Removing the link removes only the pointer. Removing the target, however, leaves the symlink dangling.
Why can I not hard link a directory?
It would let the filesystem contain loops, which would break every tool that walks the tree. Only the kernel creates the directory hard links . and .. for this reason.
Which uses less disk space?
Both are negligible. A hard link is a directory entry; a symlink is a tiny file holding a path. Neither duplicates the data.
Full guides for both
Make one file reachable from several paths — and understand symlinks vs hard links.
lsList the contents of a directory, with options for hidden files, long format, sorting and more.
findLocate files anywhere in a directory tree by name, type, size, date — and act on them.
Other comparisons
Both copy files over SSH. rsync sends only what changed; scp sends everything, every time.
curl vs wgetcurl is an HTTP client for talking to services; wget is a downloader for retrieving files.
sed vs awksed edits lines; awk understands columns. Substitution is sed, computation is awk.
grep vs ripgrep (rg)grep is everywhere; ripgrep is dramatically faster on code and respects .gitignore by default.