Is there a standard approach, when using snapper on btrfs, to exclude directories under users' home folders? Say... ~/.cache/yay on Arch. Or possibly even ~/.cache as a whole.

Of course, I know the SOP is to create a subvolume any time you want a folder's contents excluded from a snapshot of a subvolume higher in the mounted folder hierarchy. But that means making a subvolume for each excluded folder under ~/ each time a user is added. Which is, in addition to getting messy to maintain, quite a few extra steps on top of normal user creation.

I suppose I could create wrapper scripts for useradd and userdel and toss them in /usr/local/sbin so they take priority. But I thought I'd see if there isn't a more elegant approach.


It's not critical. The only system I currently have snapper deployed on is a home gateway and it's unlikely to ever have more than one non-root user. But it would be nice to know for the future.

subvolumes (excluding existing snapshots):

$ sudo btrfs subvolume list /
ID 258 gen 33625 top level 5 path home
ID 262 gen 33553 top level 5 path opt
ID 264 gen 33555 top level 5 path var-www
ID 266 gen 33630 top level 5 path arch
ID 267 gen 33631 top level 5 path var-log
ID 268 gen 33566 top level 5 path pacman-cache
ID 270 gen 45 top level 266 path var/lib/portables
ID 271 gen 46 top level 266 path var/lib/machines
ID 274 gen 33566 top level 266 path .snapshots
ID 276 gen 33556 top level 258 path home/.snapshots
ID 278 gen 33556 top level 262 path opt/.snapshots
ID 279 gen 33556 top level 264 path var-www/.snapshots


# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f / btrfs rw,noatime,compress=zstd:3,ssd,space_cache,subvolid=266,subvol=/arch,subvol=arch 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /.snapshots btrfs rw,nodev,noexec,noatime,compress=zstd:3,ssd,space_cache,subvolid=274,subvol=/arch/.snapshots,subvol=arch/.snapshots 0 0

# /dev/sda1
UUID=27d5943f-e74d-480f-be46-a370c5b1f37f /boot ext4 rw,noatime,nodev,nosuid,noexec 0 2

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /home btrfs rw,noatime,nodev,compress=zstd:3,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /home/.snapshots btrfs rw,nodev,noexec,noatime,compress=zstd:3,ssd,space_cache,subvolid=276,subvol=/home/.snapshots,subvol=home/.snapshots 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /opt btrfs rw,noatime,nodev,nosuid,compress=zstd:3,ssd,space_cache,subvolid=262,subvol=/opt,subvol=opt 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /opt/.snapshots btrfs rw,nodev,noexec,noatime,compress=zstd:3,ssd,space_cache,subvolid=278,subvol=/opt/.snapshots,subvol=opt/.snapshots 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /var/log btrfs rw,noatime,nodev,nosuid,noexec,compress=zstd:3,ssd,space_cache,subvolid=267,subvol=/var-log,subvol=var-log 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /var/www btrfs rw,noatime,nodev,nosuid,noexec,compress=zstd:3,ssd,space_cache,subvolid=264,subvol=/var-www,subvol=var-www 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /var/www/.snapshots btrfs rw,nodev,noexec,noatime,compress=zstd:3,ssd,space_cache,subvolid=279,subvol=/var-www/.snapshots,subvol=var-www/.snapshots 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /var/cache/pacman/pkg btrfs rw,noatime,nodev,nosuid,noexec,compress=zstd:3,ssd,space_cache,subvolid=268,subvol=/pacman-cache,subvol=pacman-cache 0 0

# /dev/sda5
UUID=5415bf33-0a89-4a36-a224-27dbb4c43977 none swap defaults 0 0
  • 2
    when a subvolume is mounted, nested subvolumes are mounted as well, automatically, no need to be in fstab Mar 29, 2020 at 19:55
  • 2
    @Andre While true, my understanding is that such would create problems when rolling back a snapper snapshot. The solution for which is to explicitly mount subvolumes where they belong. Mar 30, 2020 at 13:52

1 Answer 1


The granularity of snapper (with BTRFS) is the BTRFS snapshot. Given the boundary of snapshots is the BTRFS subvolume, no you cannot configure snapper to exclude directories/folders. snapper simply doesn't have any control over this.

On my system I do exactly as you mentioned; Create subvolumes for the directories I don't want to snapshot.

To set up this approach during the creation of user accounts, you can create a skelleton (skell) directory which contains a shell script which upon user login creates the necessary subvolumes, if they don't already exist; With BTRFS, non-root users can create subvolumes (but cannot delete them).

Said skelleton directory will be copied to the user's home directory when using useradd. Then, when the user first logs in the subvolumes for, say .cache, would be created. No need for wrapper scripts. See man useradd.

  • 2
    Ah, I didn't realize subvolumes could be created by non-root users. That does simplify things. TY! Aug 20, 2019 at 19:50
  • I also realize just now that subvols can be created by non-root user. In addition, I also found that although non-root user can not delete the subvol using btrfs subvol delete, but the user is allowed to simply do rmdir subvol or rm -r subvol, which can effectively delete the subvol.
    – doraemon
    Jan 9, 2022 at 13:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .