This is the second post in a series showcasing advanced features of Guix. You can read the first part here.
As you may know, Guix upgrades are transactional: the new state is computed up-front and "switched to" in one atomic operation. Unlike some other package managers (and real life for that matter!), it is not possible to get into a partially completed upgrade situation.
Also unlike real life, a bad transaction can always be
rolled back.
If you messed up your system somehow, the resolution is a simple
guix system roll-back
away. No need to say "I'm sorry, we need to start
over" to your mom who just wanted to install that totally legitimate looking
casino game.
Naturally this luxury uses more disk space than a traditional happy-go-lucky
operating system. That's where guix gc
comes in. When called without any
arguments, guix gc
will delete all store items (i.e. packages) that are not
in use by active system generations (or user profiles).
However that alone won't free up disk space from old generations that are no
longer useful. To do that you first need to run guix system delete-generations
to make those eligible for garbage collection:
$ sudo guix system delete-generations 3m
deleting /var/guix/profiles/system-122-link
deleting /var/guix/profiles/system-123-link
deleting /var/guix/profiles/system-124-link
building /gnu/store/r8g38hm98wcz5vn46ifv1ylrs525rvqp-grub-locales.drv...
building /gnu/store/0764m04djxrn0b85nzdmp8chfrci0jdj-grub.cfg.drv...
building /gnu/store/pgrr3q31z4wq3bwrc715aaynglrq7zmh-install-bootloader.scm.drv...
This deleted all generations older than three months and also removed the entries from the bootloader menu. All gone, just like that! If you don't pass a date argument, everything except the current generation will be deleted. Better make sure you won't regret that later (like I have!).
To clear old generations from your user profile, use
guix package --delete-generations
:
$ guix package --delete-generations=3m
deleting /var/guix/profiles/per-user/marius/guix-profile-35-link
deleting /var/guix/profiles/per-user/marius/guix-profile-36-link
deleting /var/guix/profiles/per-user/marius/guix-profile-37-link
deleting /var/guix/profiles/per-user/marius/guix-profile-38-link
Notice that it only deletes links
, not actual packages. If we now run
guix gc
, the packages inside those profile generations will be deleted
(as long as they are not referenced by other generations).
Conveniently guix gc
can delete old generations and clear up disk space
in one go. This also includes generations from guix pull
and guix home
:
$ guix gc --delete-generations=3m
deleting /var/guix/profiles/per-user/marius/current-guix-14-link
deleting /var/guix/profiles/per-user/marius/current-guix-15-link
deleting /var/guix/profiles/per-user/marius/current-guix-16-link
deleting /var/guix/profiles/per-user/marius/guix-home-52-link
deleting /var/guix/profiles/per-user/marius/guix-home-53-link
deleting /var/guix/profiles/per-user/marius/guix-home-54-link
finding garbage collector roots...
[... lots of output about deleted packages ...]
deleting `/gnu/store/trash'
deleting unused links...
note: currently hard linking saves 627740.99 MiB
guix gc: freed 80,173.42858 MiBs
If you run this command as root or with sudo
, it will clear old generations
from all users which is useful on a multi-user system.
For developers who just want to free up some space, but not necessarily delete everything (because they will inevitably need some of the unreferenced packages later), there are handy flags to only control how much to delete.
For example, to clear up 40GiB for that other operating system you want to try in a VM:
guix gc -C 40G
Or if you want to make 100GiB available on the system:
guix gc -F 100G
This differs from -C
in that it will stop once the free disk space reaches
100GiB. If you already have 100GiB available space, the command does nothing.
The latter is useful as a cron job to make sure the store does not take up the whole disk, while not deleting all those builds you worked so hard for (but did not install to a profile).