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.
Every whole-system Linux file backup starts from an exclusion list. Some of it is unavoidable: parts of the directory tree are not files at all but windows into the running kernel. Some of it is a judgement about what can be rebuilt. And some of it, on many servers, was copied from a forum post years ago and has not been looked at since.
An exclusion list can fail in two directions. Too short, and the backup tries to read kernel interfaces, stores gigabytes of throwaway data, or stalls on a device file. Too long, and real data is left out, the job still reports success, and the gap appears only when someone needs a file that was never there.
This guide works through the Linux directory tree using the published hierarchy specifications, explains the exclusion mechanisms that restic, Borg and rsync document, and sets out how to check your list against what the server actually holds. A companion guide in this series covers the same problem on Windows, where the FilesNotToBackup registry list does the excluding.
Why it matters
Linux servers in small and mid-sized estates are often backed up with a file-level tool pointed at /, plus a list of things to skip. That works well when the list reflects the server. It works badly when software has been installed since, when a directory's purpose has changed, or when a mount has been added (our reading).
Three properties make exclusion mistakes hard to see:
- A skipped directory produces no error. The backup did what it was told.
- Restores are usually partial. People restore one folder, not a whole server, so a missing directory elsewhere goes unnoticed.
- Some exclusions are automatic. Tools that honour cache tags or stay on one file system will leave things out without a line in your own list saying so.
How the Linux tree divides up
Two documents describe where things belong on a modern Linux system. The hier(7) manual page gives the traditional layout. The UAPI Group's Linux File System Hierarchy specification, which systemd's file-hierarchy(7) page now points to, divides the tree into "static installed files, persistent data, and ephemeral runtime files." That three-way split is a good basis for a backup decision.
Kernel interfaces: exclude
/proc and /sys are not storage. The UAPI specification describes /proc as "A virtual kernel file system exposing the process list and other functionality", and says of both /proc and /sys that each is "mostly an API to interface with the kernel and not a place where normal files may be stored."
/dev is "The root directory for device nodes", usually "mounted as a devtmpfs instance", and "managed jointly by the kernel and a userspace component such as systemd-udevd". Reading device nodes as if they were files can mean reading a whole disk, or blocking forever on a device that never returns end-of-file (our understanding).
Back these up and you gain nothing; the next boot recreates them. Exclude them by mount type rather than by name where the tool allows it (see below).
Runtime and temporary data: usually exclude
/run "is flushed on boot", according to the UAPI specification. hier(7) describes it as containing "information which describes the system since it was booted." Process identifier files, sockets and lock files belong here. Restoring them onto a running system would be meaningless at best (our reading).
/tmp is "The place for small temporary files", "usually mounted as a tmpfs instance", and "usually flushed at boot-up." The specification adds that "files that are not accessed within a certain time may be automatically deleted." hier(7) says the same: files "may be deleted with no notice, such as by a regular job or at system boot up."
/dev/shm holds POSIX shared memory and "is flushed on boot, and is a tmpfs file system."
/var/tmp is different, and is the first common mistake. The UAPI specification calls it "The place for larger and persistent temporary files", notes it "is usually mounted from a persistent physical file system", and says it "is generally not flushed at boot-up". Applications sometimes keep long-running work files here, such as partly built exports or upload staging (our understanding). Excluding /var/tmp because its name ends in tmp is a judgement, not a rule.
Caches: exclude with care
The UAPI specification describes /var/cache as "Persistent system cache data" and says "Flushing this directory should have no effect on operation of programs, except for increased runtimes necessary to rebuild these caches." It uses the same words for each user's ~/.cache.
That is a promise about how well-behaved programs use the directory, not a guarantee about what is in it on your server. An application that stores something it cannot rebuild under /var/cache is badly behaved, but the backup still loses it (our reading). Check what is in the cache directories before excluding them wholesale.
Persistent data: back up
The directories that matter most are the ones easiest to treat as system clutter:
/etc: configuration. Thehier(7)page describes it as containing "configuration files which are local to the machine."/var/lib: "Persistent system data." This is where many databases, package managers and services keep their state./var/log: "Persistent system logs." Often needed for investigation after an incident, and sometimes for compliance (our reading)./var/spool: "Spooled (or queued) files for various programs", including scheduled jobs and, on some systems, mail./srv: "The place to store general server payload, managed by the administrator."/homeand/root: user and administrator files. The specification notes that root's home is placed outside/home"in order to make sure the root user may log in even without /home/ being available and mounted."/optand/var/opt: third-party software and, in/var/opt, where it "stores its persistent, variable data."
Live database files under /var/lib need application-consistent backup, not just a file copy. That is a separate topic, covered in our articles on database backups.
The exclusion mechanisms tools provide
Staying on one file system
restic, Borg and rsync all have an option that stops the backup crossing into another mounted file system. The restic manual explains that with --one-file-system, if you back up / and have external media mounted under /media/usb, "restic will not back up /media/usb at all", and that "Virtual filesystems such as /proc are also considered different and thereby excluded". rsync's equivalent is --one-file-system, -x ("don't cross filesystem boundaries"). Borg's -x documentation explains that it detects these boundaries by comparing a directory's device number with its parent. Same-device bind mounts can therefore remain in scope, whereas Btrfs subvolumes can introduce different device numbers without being separate mounts (Borg 1.4.5).
This is the cleanest way to leave out /proc, /sys, /dev and tmpfs mounts, because it follows what is mounted rather than what a directory is called. It also has a cost that catches people out: a separate data volume mounted at /srv or /var/lib/mysql is excluded too, unless it is listed as a source in its own right. Borg's manual warns that "there are directories with device numbers different from their parent", and advises "when using --one-file-system, you should double-check that the backup works as intended." restic notes that you can list several file systems on the command line and each will be backed up.
Btrfs subvolumes add a further twist. The restic manual says --one-file-system prevents "crossing filesystem boundaries and subvolumes", so a server with /home on a separate subvolume can lose it from a backup of / (our reading).
Cache directory tags
The Cache Directory Tagging Specification lets an application mark a directory as a cache by placing a file named CACHEDIR.TAG in it. The file "must consist of the following ASCII header string": Signature: 8a477f597d28d172789f06886806bc55. The specification's stated purpose is "to make it easy to avoid backing up or copying cached data unnecessarily from one machine to another."
restic's --exclude-caches and Borg's --exclude-caches both honour the tag. Neither is on by default in the commands documented; they are options you choose (our reading of the manuals).
The specification itself warns about the risk. Blind use of tags is the problem: "use of cache directory tags in automatic system backups could potentially increase the damage that intruders or malware could cause to a system", because a user is "substantially less likely to notice the malicious insertion of a CACHDIR.TAG into an important directory than the outright deletion of that directory". (The misspelling is in the original.) Its recommendation is that "backup software should at least inform the user which directories are being omitted due to the presence of cache directory tags", and that tags "should only be treated as hints", not as the last word on what is backed up.
Marker files and size limits
restic's --exclude-if-present excludes "a folder's content if it contains a file called foo". Borg has the same option. These let any user with write access to a directory remove it from the backup by creating one file, which has the same risk as cache tags (our reading).
restic's --exclude-larger-than skips files above a size. It is useful for keeping disk images or exports out of a file backup that is not meant to hold them, but it will also skip a large database dump that someone moved into a backed-up folder on purpose (our reading).
Explicit sources override excludes
One restic detail is worth knowing: "Excludes do not apply to backup sources that were explicitly passed to the backup command." The manual immediately qualifies this: "This only applies to the exact paths that were explicitly passed to the backup command. Content inside a directory you back up is still filtered by the given excludes." For example, explicitly listing the directory /srv/reports does not protect its child old.tmp from an exclusion matching that child. Explicitly listing the file /srv/reports/old.tmp itself invokes the exception for that exact file.
Checking your exclusions against the server
All of these commands only read.
See what is mounted, and what type it is. findmnt "will list all mounted filesystems or search for a filesystem." Its --real option prints "only real filesystems" and --pseudo prints "only pseudo filesystems":
findmnt --real
findmnt --pseudo
Account for every required data area in the mount inventory, then compare actual snapshot coverage with that inventory and the source list. A mount point is not necessarily a different device: rsync treats a bind mount to the same device as the same file system, and Borg documents device-number comparisons rather than a universal mount boundary. Apply the installed tool's device and subvolume rules; separately include required areas that those rules would skip, and check that other filters do not remove their contents.
See how much each top-level area holds. A disk usage summary of the persistent areas shows whether something large has appeared since the list was written:
du -xsh /etc /var/lib /var/log /var/spool /var/tmp /var/cache /srv /opt /home /root
Find candidate cache tags and marker files. Review the actual backup source paths and mount inventory first. This documented read-only example is partial: it searches from / without descending into other devices; it does not enumerate every skipped directory:
find / -xdev -name CACHEDIR.TAG -type f
Run a reviewed search separately for every actual backup source and relevant file system, substituting its starting path. Retain and inspect errors; do not suppress access failures or describe unreadable areas as covered. Repeat for the exact marker names configured in the job. find -xdev limits device traversal, not the scope of all your backup sources.
A matching filename is only a candidate. Validate that the first 43 bytes of each cache tag are exactly Signature: 8a477f597d28d172789f06886806bc55, including case and with no preceding whitespace, as the tag specification requires. Then check the installed backup tool, active options and marker rules, and compare candidates against the job's recorded exclusions and snapshot contents. Investigate unexpected tags in project or database directories; a valid tag does not by itself prove that this job honours it.
Read the backup tool's own record. Most tools can list the contents of a snapshot. Compare the top-level directories in the latest snapshot with the list of what should be there.
A sensible starting list
As a starting point, and to be adjusted for each server (our recommendation):
| Path | Default | Reason |
|---|---|---|
/proc, /sys, /dev |
Exclude (by one-file-system or type) | Kernel interfaces, recreated at boot |
/run, /dev/shm |
Usually exclude after workload review | Runtime data flushed at boot; /dev/shm uses tmpfs |
/tmp |
Review, usually exclude | Usually transient; depends on distribution cleanup and mount configuration. Identify and protect any irreplaceable workload data before exclusion |
/var/tmp |
Review | Persistent; may hold work in progress |
/var/cache, ~/.cache |
Review, usually exclude | Rebuildable if programs behave |
/etc, /var/lib, /var/log, /var/spool |
Back up | Configuration, state, logs, queues |
/srv, /opt, /var/opt |
Back up | Server payload and third-party software |
/home, /root |
Back up | User and administrator files |
| Separate data devices/subvolumes | Include as sources where required by the tool | Check device/subvolume boundaries and descendant exclusions; same-device bind mounts are not necessarily skipped |
| Swap files | Exclude | Memory overflow, not data (our understanding) |
Worked example (illustrative)
The following is invented to show the pattern. A web agency runs a Linux server with sites in /srv/www and a database on a separate disk mounted at /var/lib/postgresql. The nightly backup runs restic against / with --one-file-system and --exclude-caches. A database dump is also written nightly to /var/backups/db.
Two years later, the server needs rebuilding. The site files restore cleanly. The database directory is empty in the backup, because it was a separate mount. The agency turns to the nightly dumps and finds the folder is missing too. A developer had once created a valid CACHEDIR.TAG, including the required signature, in /var/backups while testing a build tool, and the active cache exclusion had skipped the dumps ever since.
A mount inventory, per-source tag audit and snapshot comparison could have exposed both gaps. The agency now independently protects the completed database dumps through a reviewed exclusion policy, verifies that the chosen recovery points actually contain them, and tests database recovery from those dumps in an isolated environment. Adding the live database mount alone would not establish application-consistent recovery. If the agency chooses direct database backup instead, it needs a separately documented and verified application-consistent method; this article does not prescribe a PostgreSQL procedure. It compares snapshot contents with the expected data map after every change.
Risks and limits
- Distributions differ. The UAPI specification and
hier(7)describe conventions; individual packages may store data elsewhere. Check what your own software writes, and where. - Do not exclude
/var/libwithout identifying and independently protecting all required persistent state. Simply including live database files is not enough; use a separately verified application-consistent database method or verified recoverable dumps. - One-file-system options interact with containers, bind mounts and Btrfs subvolumes in ways that differ by tool and version. Test the result rather than reasoning from the option name.
- Tag-based and marker-based exclusions can be created by any user with write access. Prefer a reviewed central list for system backups.
- The commands above read only. A full
duorfindacross a large server can take time and add I/O; run them at a quiet time. - This guide covers file-level backup. Image-level and snapshot-based backups follow different rules.
Sources
All accessed 14 November 2026.
- UAPI Group, UAPI.9 Linux File System Hierarchy: https://uapi-group.org/specifications/specs/linux_file_system_hierarchy/
- man7.org, hier(7): https://man7.org/linux/man-pages/man7/hier.7.html
- man7.org, file-hierarchy(7): https://man7.org/linux/man-pages/man7/file-hierarchy.7.html
- man7.org, proc(5): https://man7.org/linux/man-pages/man5/proc.5.html
- Linux kernel documentation, sysfs: https://docs.kernel.org/filesystems/sysfs.html
- man7.org, tmpfs(5): https://man7.org/linux/man-pages/man5/tmpfs.5.html
- man7.org, tmpfiles.d(5): https://man7.org/linux/man-pages/man5/tmpfiles.d.5.html
- man7.org, findmnt(8): https://man7.org/linux/man-pages/man8/findmnt.8.html
- man7.org, rsync(1): https://man7.org/linux/man-pages/man1/rsync.1.html
- Bryan Ford, Cache Directory Tagging Specification: https://bford.info/cachedir/
- restic documentation 0.19.1, Backing up: https://restic.readthedocs.io/en/stable/040_backup.html
- Borg documentation 1.4.5, borg create: https://borgbackup.readthedocs.io/en/stable/usage/create.html
Related future topics
- The files Windows leaves out of a backup on purpose: FilesNotToBackup and FilesNotToSnapshot
- Checking a restic or Borg repository: what check and verify prove
- Backing up Docker hosts: volumes, bind mounts and what a host backup misses
This article was originally published on .