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
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
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
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).
guix gc can delete old generations and clear up disk space
in one go. This also includes generations from
guix pull and
$ 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).