Since we are referring to a one-time event to compress the data, there is little reason not to apply to an SSD. The lifespan of most SSDs won’t be materially impacted by that. Especially since the compression won’t be applied to files where the compression wouldn’t yield results which will include most larger files that are likely to be found on a desktop.
You could view the BTRFS filesystem as an hard disk with a partition table, where the root filesystem is the primary partition and sub-volumes are the extra partitions.
The BTRFS filesystem allows you to access all directory tables in all partitions without the need to mount the partitions separately, except for the primary partition which you mount at the time you mount the BTRFS filesystem.
Because of this you are able to access every directory and file in the whole BTRFS filesytem while the needed info of some directories and files are kept in a different table (partition) transparent to the user.
Thank you all for your valuable input.
The current status is, I still use systemd-homed and when it detects that the /home
partition is btrfs, it will automatically create a subvolume (for each user, I only have one) and mount the directory /home/username.homedir
into /home/username
.
This is a directory mount, systemd-homed could also mount a luks or differently encrypted image file which makes more sense than a folder mount.
So, it create a ephemeral mount home-username.mount
which does exactly this.
It also shows up in /proc/mounts
:
grep home /proc/mounts
/dev/mapper/crypthome /home btrfs rw,noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvolid=5,subvol=/ 0 0
/dev/mapper/crypthome /home/username btrfs rw,nosuid,nodev,noatime,idmapped,compress=zstd:3,ssd,discard=async,space_cache=v2,subvolid=5,subvol=/ 0 0
The options in the first row are set by me, the second ones by systemd. There is no home-username.mount
file anywhere. I can only see the specifics with systemctl show home-username.mount
.
Then, the mystery begins.
We have output:
sudo btrfs subvolume show /home
/
Name: <FS_TREE>
UUID: 00487190-dd99-4034-b8c2-01170924c98e
Parent UUID: -
Received UUID: -
Creation time: 2023-03-03 13:23:50 +0100
Subvolume ID: 5
Generation: 935
Gen at creation: 0
Parent ID: 0
Top level ID: 0
Flags: -
Send transid: 0
Send time: 2023-03-03 13:23:50 +0100
Receive transid: 0
Receive time: -
Snapshot(s):
But for the user’s supposed subvolume:
$ sudo btrfs subvolume show /home/username
ERROR: Not a Btrfs subvolume: Invalid argument
However, the subvolume for the archived projects from a few posts before is there:
$ sudo btrfs subvolume show /home/username/archives
username.homedir/archives
Name: archives
UUID: 444be83c-5670-0e41-84f1-c91f2d25e4f8
Parent UUID: -
Received UUID: -
Creation time: 2023-03-03 21:01:41 +0100
Subvolume ID: 256
Generation: 901
Gen at creation: 877
Parent ID: 5
Top level ID: 5
Flags: -
Send transid: 0
Send time: 2023-03-03 21:01:41 +0100
Receive transid: 0
Receive time: -
Snapshot(s):
But I can’t find any information about the mount info, it’s not a systemd-unit or in /proc/mounts
.
As opposed to the discussion above, I think I was able to set the compression level of this subvolume with
$ sudo btrfs property set /home/username/archives compression zstd:9
Which I can verify with:
$ sudo btrfs property get /home/username/archives compression
compression=zstd:9
However, I don’t know if this is overridden by the parent mount or an invalid option.
I did some tests and a 100MB file from here and compressed it with the levels 1, 3, 8, 12, and 19 on a tmpfs:
100.000.000 100M
40.678.709 100M-L1.zst
37.372.605 100M-L2.zst
35.487.160 100M-L3.zst
31.607.256 100M-L8.zst
30.413.324 100M-L12.zst
26.954.633 100M-L19.zst
And to check on btrfs, I copied the file to the /home/username/archives
subvolume and run compsize:
Processed 1 file, 763 regular extents (763 refs), 0 inline.
Type Perc Disk Usage Uncompressed Referenced
TOTAL 39% 39960576 100003840 100003840
zstd 39% 39960576 100003840 100003840
From what I see, it’s closest to compression level 1 when looking closely on the bytes.
So, it is smaller than level 1 but larger than level 2. Shouldn’t it be closer to level 3 if we can cut some slack on overhead? But the property that I’ve set above with using level 9 is surely not applied.
Try this instead:
systemctl status /home/username
It should show you how systemd mounted it, to see the actual config you could use cat
instead of status
.
$ sudo systemctl status /home/username
● home-username.mount - /home/username
Loaded: loaded (/proc/self/mountinfo)
Active: active (mounted) since Mon 2023-03-06 09:17:41 CET; 3h 45min ago
Where: /home/username
What: /dev/mapper/crypthome
For cat
: No files found for home-username.mount.
The info is there with
systemctl show /home/username
Where=/home/username
What=/dev/mapper/crypthome
Options=rw,nosuid,nodev,noatime,idmapped,compress=zstd:3,ssd,discard=async,space_cache=v2,subvolid=5,subvol=/
Type=btrfs
TimeoutUSec=1min 30s
ControlPID=0
DirectoryMode=0755
SloppyOptions=no
LazyUnmount=no
ForceUnmount=no
ReadWriteOnly=no
Result=success
UID=[not set]
GID=[not set]
Slice=system.slice
[...]
Id=home-username.mount
Names=home-username.mount
Requires=dev-mapper-crypthome.device home.mount -.mount system.slice
Conflicts=umount.target
Before=local-fs.target session-2.scope umount.target
After=local-fs-pre.target systemd-journald.socket blockdev@dev-mapper-crypthome.target system.slice home.mount -.mount dev-mapper-crypthome.device
RequiresMountsFor=/home
Description=/home/username
LoadState=loaded
ActiveState=active
FreezerState=running
SubState=mounted
SourcePath=/proc/self/mountinfo
StateChangeTimestamp=Mon 2023-03-06 09:17:41 CET
StateChangeTimestampMonotonic=67906042
InactiveExitTimestamp=Mon 2023-03-06 09:17:41 CET
InactiveExitTimestampMonotonic=67906042
ActiveEnterTimestamp=Mon 2023-03-06 09:17:41 CET
ActiveEnterTimestampMonotonic=67906042
ActiveExitTimestampMonotonic=0
InactiveEnterTimestampMonotonic=0
CanStart=yes
CanStop=yes
CanReload=yes
CanIsolate=no
CanFreeze=no
StopWhenUnneeded=no
RefuseManualStart=no
RefuseManualStop=no
AllowIsolate=no
DefaultDependencies=yes
OnSuccessJobMode=fail
OnFailureJobMode=replace
IgnoreOnIsolate=yes
NeedDaemonReload=no
JobTimeoutUSec=infinity
JobRunningTimeoutUSec=infinity
JobTimeoutAction=none
ConditionResult=no
AssertResult=no
ConditionTimestampMonotonic=0
AssertTimestampMonotonic=0
Transient=no
Perpetual=no
StartLimitIntervalUSec=10s
StartLimitBurst=5
StartLimitAction=none
FailureAction=none
SuccessAction=none
InvocationID=d890471d826e44e9a6b04b394223e61f
CollectMode=inactive
But this doesn’t show any btrfs information. It could be anything (luks volume, ecryptfs or whatever else systemd supports.).
Please be aware, that btrfs will NOT compress a file as one block of data, but will break it up in several small chunks. This may affect compression ratio. This is visible if you look onto fragmentation of a compressed file.
Level 3 is very good. I use Level 9 overall and have better then 2:1 over all files.
Sure, thanks, I’ll plan on using something between 8 and 12, however, currently I don’t even know if it’s using compression and of so, which level and where it’s configured.
The test would indicate that it’s using the default level 3.
There is no way to set this or even check which one is used.
mount |grep -E btrfs
/dev/sda2 on / type btrfs (rw,noatime,compress=zstd:9,ssd,space_cache,commit=300,subvolid=36033,subvol=/@
Read the docs of the developers It is what it says
But the subvolume is not mounted by me or ay unit I can find. It seems it’s transient (?). It’s not listed in the mounts.
The sentence is confusing, the compression level can be set during mounting the subvolume but is shared. So which one is it?
Edit:
Okay, so the subvolume can’t be mounted by name, however, with subvolid it can be mounted:
sudo mount -o subvolid=256,compression=zstd:9,noatime /dev/mapper/crypthome archives
but the compression level is not applied:
$ grep archives /proc/self/mounts
/dev/mapper/crypthome /home/username.homedir/archives btrfs rw,noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvolid=256,subvol=/username.homedir/archives 0 0
So, I can understand the docs: the compression level can be set during mount (can as it can be set without failing), however, it is then overwritten by the parent volume (what they weirdly call shared.)
I only found a few posts from 10-12 years ago complaining about this, but they all end in a “they are working on it” and “it works now” (the latter is probably falling for the same logic that it doesn’t error out when setting the level) and the first one is from their wiki
Can I set compression per-subvolume?
Currently no, this is planned. You can simulate this by enabling compression on the subvolume directory and the files/directories will inherit the compression flag.
So, @andreas85’s idea of differently compressed subvolumes doesn’t work.
So bear with me here, I have an idea.
I have mounted /home
in fstab and a mysterious subvolume to /home/username
and then my archived subvolume. So far so good.
From a few experiments, I would very much have the archive subvolume at zstd:12. I almost never write to it (once every few months, I can wait for the copy, no problem) and reading doesn’t need to be realtime.
As the root volume ( here /home
) is mounted with zstd:3
, couldn’t I “just” for copying files to the archive remount the full volume? In TTY, this should be relatively easy, right?
# On TTY1
sudo umount /home
sudo mount -o defaults,noatime,compress=zstd:12 /dev/mapper/crypthome /home
# On TTY2
rsync -av --info=progress2 /home/username/project/a /home/username/archive/
logout
# On TTY1
sudo umount /home
sudo mount -a
Or am I totall out of place?
I’m not sure if you are able to unmount /home
while loged into a normal user (non-root) in the GUI, because of some files keeping that mount bussy.
You could try it on the console yea maybe…
did i say something funny?
ahhh TTY
= console right?
Today, I checked systemd-homed in VM.
I noticed that systemd-homed creates a new separate filesystem for a new user, that means each homed-user has its own file system that is independent of other file system on home partition.
fstab is useless for systemd-homed. But systemd-homed has nice configuration:
Check homectl --help
to show the mount option: --luks-extra-mount-options
sudo homectl update [USER_NAME] --luks-extra-mount-options=‘compress=zstd:9’
$ systemctl show home-user.mount
Where=/home/user
What=/dev/mapper/home-user
Options=rw,nosuid,nodev,relatime,idmapped,compress=zstd:9,ssd,noacl,space_cache=v2,subvolid=256,subvol=/user
It shows zstd:9. That works!
Is that called uhm…“Filesystem namespace” or something?
Like a virtual network but this time a virtual filesystem…
Not completely related to what i wrote above but still nice to link in this topic:
AFAIK, the native filesystem is stored in user.home as a file.
There is my clear proof in VM to show:
Why I have two Btrfs filesystems:
$ sudo btrfs filesystem show
Label: 'System' uuid: 8b945945-d355-4de3-9c51-820a66b79dc2
Total devices 1 FS bytes used 24.52GiB
devid 1 size 27.95GiB used 27.95GiB path /dev/sda2
Label: 'user' uuid: d0f5beb9-f237-4596-842a-93ad894684f2
Total devices 1 FS bytes used 32.90MiB
devid 1 size 13.90GiB used 1.52GiB path /dev/mapper/home-user
One for the system partition, others for homed-user.
Yes systemd-homed does that indeed, as far as i could read the docs for it.
But i meant the way it is mounted, is not like a regular mount, but instead a containerized mount using namespaces…
I can’t at moment find the info referring to that otherwise i would have linked to that.
Anyway what i understood back then is that it works similar to PrivateTemp etc with respect to access to other processes…
I could be totaly fried again at this hour, so in that case just ignore my late night blabler as usual
The behavior of user.home as systemd-homed file is similar to Veracrypt , that is just logic.
Systemd-Homed would be a bit cumbersome because filesystems run on top of other filesystem. Of course, performance will be reduced and lower stability.
I like to use LUKS partition instead of systemd-homed.

I like to use LUKS partition instead of systemd-homed.
See the UUID: 773f91ef-66d4-49b5-bd83-d683bf40ad16
in:
Which makes me believe you are able to use partitions also instead of a file mounted via a loopback device…
Escpecially when using Luks…
Thank you for investigating. In my case, I don’t have a separate filesystem because I don’t use LUKS with systemd-homed.
From my post above, I’ve done exactly this:
- Logged out (systemd unmounts
/home/username
) - Switch to TTYx and log in as root (no
/home
needed) - Umount
/home
- Mount
/home
with additional optioncompress=zstd:12
- Switch to TTYy and log in as username (systemd now mounts
/home/username
) - The compression option is inherited:
compress=zstd:12
is listed in/proc/mounts
- Move all directories/files from their old location to the
/home/username/archives
subvolume - Log out
- Switch back to TTYx, unmount
/home
,mount -a
- Log in graphical environment: Done.
I can see with compsize
that the /home/username/archives
directory takes less disk space and has a higher zstd
column than the old locations with zstd:3
.
To maintain level 12, I’ve set the subvolume to read-only (btrfs property set . ro true
), which, obviously, must be reset prior to writing above.
A job well done! Thank you all for participating, it wouldn’t have been possible without you.
This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.