Taming Disk Usage with btrfs Snapshots and Automatic Pruning

Introduction to btrfs Snapshots

I’ve been using btrfs for years, and one of its most powerful features is snapshotting. This allows you to create a point-in-time copy of your data, which is incredibly useful for backups, testing, and deploying new software versions. However, managing these snapshots can become cumbersome, especially when dealing with limited disk space. The real trick is to automate the process and set up a pruning system to keep your disk usage in check.

Creating btrfs Snapshots

To get started with btrfs snapshots, you’ll need to have a btrfs file system set up on your system. Once you have btrfs installed and configured, creating a snapshot is straightforward:

btrfs subvolume snapshot /path/to/source /path/to/destination

For example, to create a snapshot of the root file system (/) and save it to the /snapshots/20260706 directory, you’d use:

btrfs subvolume snapshot / /snapshots/20260706

Don’t bother with trying to manage these snapshots manually, though - it’s a recipe for disaster.

Automatic Snapshotting with systemd

To automate the snapshotting process, I usually start with systemd. You can create a new file in the /etc/systemd/system directory called btrfs-snapshot.service:

[Unit]
Description=btrfs snapshot service
[Service]
Type=oneshot
ExecStart=/usr/bin/btrfs subvolume snapshot / /snapshots/%Y%m%d

Next, create a timer file called btrfs-snapshot.timer:

[Unit]
Description=btrfs snapshot timer
[Timer]
OnUnitInactiveSec=1d
Unit=btrfs-snapshot.service

This timer will trigger the btrfs-snapshot.service every day, creating a new snapshot of the root file system. In practice, this is a great way to ensure you have a regular backup of your system.

Automatic Pruning with systemd

While automatic snapshotting is useful, it can quickly fill up your disk with snapshots. This is where people usually get burned - they forget to set up a pruning system and end up running out of disk space. To mitigate this, you can create another service that automatically prunes old snapshots. Create a new file called btrfs-prune.service:

[Unit]
Description=btrfs prune service
[Service]
Type=oneshot
ExecStart=/usr/bin/find /snapshots -type d -mtime +30 -exec /usr/bin/btrfs subvolume delete {} \;

This service uses the find command to search for directories in the /snapshots directory that are older than 30 days and deletes them using the btrfs subvolume delete command.

Configuring the Prune Service

To configure the prune service to run at regular intervals, create a timer file called btrfs-prune.timer:

[Unit]
Description=btrfs prune timer
[Timer]
OnUnitInactiveSec=7d
Unit=btrfs-prune.service

This timer will trigger the btrfs-prune.service every 7 days, deleting any snapshots older than 30 days. I’ve seen this go wrong when the pruning service isn’t configured correctly, so make sure to test it thoroughly.

Security Considerations

When using btrfs snapshots, it’s essential to consider the security implications. Since snapshots contain a point-in-time copy of your data, they can potentially contain sensitive information. To mitigate this, make sure to set proper permissions on your snapshot directories and consider using encryption to protect your data. For more information on btrfs security, you can refer to the official btrfs documentation.

Troubleshooting

If you encounter issues with your btrfs snapshots or pruning service, you can check the systemd logs for errors. You can also use the btrfs subvolume list command to verify that your snapshots are being created correctly.

Further Reading

For more information on btrfs and its features, you can refer to the btrfs wiki or the official kernel documentation.


See also