How to Check Compressed vs. Uncompressed Size of a BTRFS Subvolume Programmatically


9 views

When working with BTRFS subvolumes where compression is enabled (-o compressed), developers often need to distinguish between:

  • Logical size (uncompressed data size)
  • Physical size (actual disk space used)

For a quick overview of compressed storage efficiency:

sudo btrfs filesystem df /path/to/subvolume

Sample output:

Data, single: total=25.00GiB, used=16.23GiB
System, single: total=32.00MiB, used=16.00KiB
Metadata, single: total=2.00GiB, used=1.45GiB

For comprehensive subvolume statistics including compression ratios:

sudo btrfs subvolume show /path/to/subvolume

Key metrics to examine:

    Name:                   mysubvol
    UUID:                   xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    Parent UUID:            -
    Received UUID:          -
    Creation time:          2023-01-01 12:00:00
    Subvolume ID:           256
    Generation:             12345
    Gen at creation:        6789
    Parent ID:              5
    Top level ID:           5
    Flags:                  -
    Snapshot(s):
    Disk total:             15.23GiB  <-- Physical size (compressed)
    Exclusive:              8.45GiB

Here's a Python script to extract both compressed and uncompressed sizes:

import os
import subprocess

def get_btrfs_sizes(path):
    # Get uncompressed size (logical)
    du = subprocess.run(['du', '-sb', path], capture_output=True, text=True)
    uncompressed = int(du.stdout.split()[0])
    
    # Get compressed size (physical)
    btrfs = subprocess.run(['btrfs', 'filesystem', 'usage', '-b', path], 
                         capture_output=True, text=True)
    compressed = int([line for line in btrfs.stdout.split('\n') 
                     if 'Device size' in line][0].split()[-1])
    
    return uncompressed, compressed

uncomp, comp = get_btrfs_sizes('/mnt/btrfs/subvol')
print(f"Compression ratio: {uncomp/comp:.2f}x")

For more detailed breakdown including compression effectiveness:

sudo btrfs filesystem usage /path/to/subvolume

This shows both allocated and used space with compression factored in.

Remember these benchmarks when choosing methods:

Method Execution Time Precision
du Slow (scans files) Uncompressed only
btrfs fi df Instant Compressed only
btrfs sub show Medium Both metrics

When working with Btrfs subvolumes using compression (mounted with -o compress), standard tools like du only show uncompressed sizes. For administrators needing accurate disk usage metrics, this presents a significant limitation.

The btrfs filesystem du command provides the most accurate view of compressed storage usage:


# Show compressed disk usage for a subvolume
sudo btrfs filesystem du -s /path/to/subvolume

# Detailed per-file breakdown
sudo btrfs filesystem du /path/to/subvolume

For systems without recent btrfs-progs, consider these methods:

Method 1: Using btrfs fi usage


sudo btrfs fi usage /mount/point -b

Method 2: Compressed size estimation


# Requires Linux 4.14+ and btrfs-progs v4.16+
sudo compsize -x /path/to/subvolume

The native btrfs commands are significantly faster than recursive du scans because they:

  • Access filesystem metadata directly
  • Don't traverse directory trees
  • Leverage Btrfs's internal accounting

Here's a typical output comparison:


# Traditional du (uncompressed size)
$ du -sh /mnt/btrfs/subvol
15G    /mnt/btrfs/subvol

# Btrfs actual compressed size
$ sudo btrfs filesystem du -s /mnt/btrfs/subvol
     Total   Exclusive  Set shared  Filename
   6.12GiB     6.12GiB       0.00B  /mnt/btrfs/subvol

Remember that:

  • Shared extents between snapshots aren't included in these calculations
  • The numbers represent actual disk usage, not logical file sizes
  • Compression ratios vary based on file types and compression algorithm