Stop losing sleep over Btrfs space accounting
Technical Briefing | 11/3/2026
You check your disk usage with df and see 60 percent used, but the underlying subvolumes have been ballooning for weeks. Btrfs reporting is notorious for being disconnected from reality because of copy-on-write overhead, snapshots, and internal fragmentation. This bit me in prod when a background job filled a disk while df lied to my face, thinking I had plenty of headroom.
Why df lies to you
The kernel doesn’t just track data blocks; it tracks extents and metadata trees. When you snapshot, you aren’t cloning data, you’re creating pointers. Most standard tools just count the bytes they see, which completely misses the shared extents that Btrfs is managing under the hood. You need to peek at the actual block group usage, not just the mount point.
btrfs filesystem usage /mountpoint
- Data and metadata are reported separately, which is exactly where most people get tripped up.
- Check the unallocated space carefully to see if you have room to grow before hitting ENOSPC.
- Don’t ignore the device breakdown; if one drive in your array is hitting limits, the whole filesystem will stop accepting writes.
Cleaning up the mess
If you are running into space issues, first verify if you have hidden snapshots taking up space that don’t show up as files. Once you delete those, the space might not show as free immediately. Run a balance if you have heavy fragmentation, but do it during off-peak hours—it’s heavy on the disk controller. If you’re really desperate, a quick rebalance with the soft filter can recover unused chunks that the allocator has been too timid to reclaim.
Keep an eye on that unallocated percentage. If it hits zero, your filesystem is effectively locked, and sometimes the only way out is adding a new block device to the pool just to get the metadata moving again.
