Let’s take a clear look at Btrfs Qgroup and Simple quotas, comparing their accounting methods and how you can switch between them.

Both features are available starting with Linux kernel v6.7, with simple quotas being introduced in v6.7.

Simple quotas (squotas) offer a straightforward method for tracking space usage by linking extents to their originating subvolumes. This approach simplifies accounting and eliminates the need for complex backreference walking. However, squotas do not track shared data, making it impossible to differentiate between shared and exclusive extents.

In contrast, Btrfs quota groups (qgroups) provide more detailed tracking, monitoring both shared and exclusive data for each subvolume. This level of granularity provides greater control but introduces added complexity and potential performance overhead, as it requires tracking shared extents and performing backreference walking.

While qgroups enable more accurate management of subvolume and snapshot data, they can impact performance. Squotas, on the other hand, operate like Btrfs with quotas disabled, where extents are permanently tied to their subvolume. Squotas are best suited for scenarios where extents are immutable and persist longer than any copies made from them.

Quick Comparison

Here’s a quick comparison between Qgroup accounting and Simple quota accounting. Basically, an extent is linked to the subvolume that first allocated it. But even if the original subvolume gets deleted, the extent stays accounted for until all references to it are gone. Also, any empty subvolume has a 16KiB node size that stores its metadata.

                 Qgroup Quota        |            Simple Quota
Create a subvolume                   |
Qgroupid    Referenced    Exclusive  |     Referenced    Exclusive   Path
--------    ----------    ---------  |     ----------    ---------   ----
0/256         16.00KiB     16.00KiB  |       16.00KiB     16.00KiB   sv1
                                     |
Write 2MB to a file                  |
Qgroupid    Referenced    Exclusive  |     Referenced    Exclusive   Path
--------    ----------    ---------  |     ----------    ---------   ----
0/256          2.02MiB      2.02MiB  |        2.02MiB      2.02MiB   sv1
                                     |
Create snapshot                      |
Qgroupid    Referenced    Exclusive  |     Referenced    Exclusive   Path
--------    ----------    ---------  |     ----------    ---------   ----
0/256          2.02MiB     16.00KiB  |        2.02MiB      2.02MiB   sv1
0/257          2.02MiB     16.00KiB  |       16.00KiB     16.00KiB   ss1
                                     |
Overwrite 1MB in the snapshot        |
Qgroupid    Referenced    Exclusive  |     Referenced    Exclusive   Path
--------    ----------    ---------  |     ----------    ---------   ----
0/256          2.02MiB      1.02MiB  |        2.02MiB      2.02MiB   sv1
0/257          2.02MiB      1.02MiB  |        1.02MiB      1.02MiB   ss1
                                     |
Delete the subvolume                 |
Qgroupid    Referenced    Exclusive  |     Referenced    Exclusive   Path
--------    ----------    ---------  |     ----------    ---------   ----
                                     |        1.00MiB      1.00MiB <squota space holder>
0/257          2.02MiB      2.02MiB  |        1.02MiB      1.02MiB   ss1

Switching to Simple Quotas

If you’re using qgroup quotas and noticing performance issues, you might want to switch to simple quotas—just as long as you don’t need to track snapshots that reference the original subvolumes where they were created.

Keep in mind, there’s no direct way to migrate to simple quotas. They start from 0 and only account for extents created after being enabled. If activated on a live filesystem, they won’t reconcile existing data or ownership (as of kernel v6.13 and btrfs-progs v6.13), but you can safely use them to start tracking from that point onward.

Enabling Simple Quotas

btrfs quota disable <mnt>
btrfs quota enable --simple <mnt>

If you’re using kernel v6.7 or later, you can check if quotas are enabled by running:

cat /sys/fs/btrfs/<UUID>/qgroups/mode

At any time, you can check if simple quotas are enabled using the script:

btrfs inspect-internal dump-super /dev/sdb | grep SIMPLE_QUOTA

Important Note

Enabling simple quotas introduces an on-disk format change that’s not compatible with older kernels. If you enable them on kernel 6.7 or later, you won’t be able to mount the device on earlier kernels such as 5.15 unless you remove the simple quotas using the command below (requires btrfs-progs version 6.13 or above):

btrfstune --remove-simple-quota <device>