meta data for this page

BTRFS compression

https://btrfs.wiki.kernel.org/index.php/Compression

Compression:

  • ZLIB – slower, higher compression ratio (uses zlib level 3 setting)
  • LZO – faster compression and decompression than zlib, worse compression ratio, designed to be fast
  • ZSTD – (since v4.14) compression comparable to zlib with higher compression/decompression speeds and different ratio levels details
    • NOTE: odler GRUB version cannot read ZSTD compressed files (from /boot)

Default compression for kernels up to 3.6 it's ZLIB. For compatibility with old kernel ZLIB is default. LZO is fast and new algo, but can be buggy.

Does a balance operation recompress files?

No. Balance moves entire file extents and does not change their contents. If you want to recompress files, use btrfs filesystem defrag with the -c option.
Balance does a defragmentation, but not on a file level rather on the block group level. It can move data from less used block groups to the remaining ones, eg. using the usage balance filter.

NOTE: Defragmentation with recompression destroys deduplication.

  • Size changed from 6,94 GB to 7,39 GB
  • After deduplication with 1024k block drops to 7.17 GB (net change in shared extents of: 490.0M)
  • After deduplication with 4k block drops from 7.17 GB to 6,94 GB(a net change in shared extents of: 306.6M)

mount options

Can be enabled during mount time:

mount BTRFS -o remount,compress=zlib
mount BTRFS -o remount,compress-force=zlib
if the first portion of data being compressed is not smaller than the original, the compression of the file is disabled – unless the filesystem is mounted with compress-force

compress-force=<method> - Enable compression even for files that don't compress well, like videos and dd images of disks.

Test data of size 651MB takes 371MB after compression.

chattr +c

Also single file compression possible using chattr +c filename.txt

To recompress exisitng files, start defragmentation with -c param:

btrfs filesystem defrag -c file.iso
btrfs filesystem defrag -c -r mydir

It is not possible to get compression ratio of file.

Internals:

  • In compressed extents, individual blocks are not compressed separately; rather, the compression stream spans the entire extent.
  • BTRFS: There is a simple decision logic: if the first portion of data being compressed is not smaller than the original, the compression of the file is disabled – unless the filesystem is mounted with compress-force

btrfs property

btrfs property set <file> compression <zlib|lzo|zstd>