Store size doubled after updating to 25.05

I switched from 24.11 to 25.05 today by replacing the channel with

nix-channel --add https://nixos.org/channels/nixos-25.05 nixos

and then doing the regular update. My root used to sit at around 25-27gb but now it gone up to 50gb (this is after running nix-collect-garbage)

Did I do something wrong when updating? How do I bring the system size back down?

Reboot into the new generation, delete the old ones, and gc.

But don’t actually, until you’ve verified that the new generation works exactly as hoped.

And a 50 gig store is small, for a desktop system, I wouldn’t even worry about it.

2 Likes

That’s not a lot if you didn’t allocate 64gb for your root partition in total.
Rebooting kind of did the trick. I was able to reclaim 10 more gigs. Maybe I can get some more from optimizing the store, but I doubt it will optimize 15 more gb to get me back where I was. Ouchie

You might want to check your systems closure size with tools like nix-tree if there is anything in the closure that is unexpected.
I want to add some more content to waffles hint, as i also think that its the most likely reason.

Nixos keeps older system generations as long as they are referenced.
As long as you don’t remove those generations that refer to 24.11 content, it will stay in the /nix/store.

ls -l /nix/var/nix/profiles | sort will list the ā€œavailableā€ system generations. You can check on the symlinks real target if there are any links to 24.11 left.
On my system it keeps 2 older generations (aside the current running).

Also please be aware that if you are using something like home-manager it might also refer own profiles, that might need a clean up and extra size as long as older release generations are around.

About the desktop closure sizes. I am running happily on a 19-20GB sized KDE desktop (unstable), running about 40GB /nix/store right now. But i did also exclude some of the higher sized default packages, that i don’t need/want on my system.

1 Like

I wouldn’t allocate less than 100 frankly. Nix is space hungry.

In case you use home-manager: dotfiles/home-config/config/clean-generations.nu at d55893bbcdfb9b38725fddf1441c5b66ba84e04c Ā· TLATER/dotfiles Ā· GitHub

I allocate 20G to my /nix, mostly so I remember to clean it up, currently sitting at 13G./ is 6M, since home and var live in separate volumes. I do recommend looking through your gcroots for anything fishy, it’s easy to accidentally have roots for stuff you don’t use at all, in my case it’s largely old devshells (kept alive by nix-direnv) or old result symlinks.

Also, don’t mix stable and unstable.

1 Like

Oh, I was completely unaware, that home manager generations need to be cleaned manually. I had 24 generations just sitting there. After I deleted all of the 24.11 generations I’m back to 25gb root partition.

1 Like

Yeah, it’s silly, especially because the home-manager docs don’t mention it and there isn’t even an option for auto-cleanup.

I finally got around to adding the above to my home.activation after having to remember how to do that for the umphteenth time… Should really just upstream that, but I’m hoping folks resolve the final issues with hjem so I can start from scratch with something that’s a bit more sane to begin with.

1 Like

While I agree, this is hard on a 32GB Librem 5 :wink:

To make the most use of small storage like this, one can create a single partition spanning the entire eMMC, which stores both / and /boot:

$ df -h / /boot/
Filesystem      Size  Used Avail Use% Mounted on
/dev/mmcblk0p1   29G   18G  9.3G  66% /
/dev/mmcblk0p1   29G   18G  9.3G  66% /boot

This avoids the struggle of a possibly too small /boot, and having unusable free space in the /boot partition

I’m calling home-manager switch in a script that first removes the oldest generation at greater-than-or-equal-to 90% disk-usage. The scripts runs as a user service:

  systemd.user = {
    services = {
      home-manager-switch = {
        Unit = {
          Description = "home-manager switch";
        };
        Service = {
          ExecStart = "/bin/sh -xc \"/home/$USER/.config/home-manager/home-manager-switch.sh\"";
        };
      };
    };
    timers = {
      home-manager-switch = {
        Unit = {
          Description = "home-manager switch";
        };
        Timer = {
          OnCalendar = "*:0/30";
          Persistent = "true";
          RandomizedDelaySec = "900";
        };
        Install = {
          WantedBy = [
            "default.target"
            "timers.target"
          ];
        };
      };
    };
  };

/.config/home-manager/home-manager-switch.sh:

#!/run/current-system/sw/bin/bash

set -auEeo pipefail

PATH="$PATH:/run/current-system/sw/bin:/home/$USER/.nix-profile/bin"

if test -n "$(df -h ~/. | grep -E '9[0-9]%|100%')"
then
    df -h ~/.
    home-manager remove-generations "$(home-manager generations | tail -1 | sed 's/^.* id //; s/ -> .*$//')"
    nix-collect-garbage
    nix-store --gc
    nix-store --optimise
fi

home-manager switch

Interesting approach, it’s less likely to leave you unable to roll back after a bunch of experimentation, since small changes won’t churn through and immediately delete loads of generations. OTOH the disk space use also ends up quite unpredictable, and this is obviously not really sensible on systems with more disk space (though I can see a world where you set a soft limit for the nix store/partition size).

Never a big fan of doing this kind of shenanigans in bash, of course, much happier with my nushell implementation :wink:

I’d suggest just adding the generation cleanup thing as an ExecStartPre to the built-in home-manager.autoUpgrade instead of rolling your own unit entirely, though.

1 Like

That is fair:

$ home-manager generations | wc -l
418
$ df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p3  3.7T  280G  3.4T   8% /

The solutions is primarily to ā€˜protect’ disk usage on smaller systems:

$ home-manager generations | wc -l
1
$ df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/mmcblk1p3   29G   21G  8.2G  72% /

Reason for rolling my own is that I update flake.lock on one server, and pull that flake.lock to my other devices.

Also:

Does this even work with flakes?

Nope! The NixOS equivalent does, and would work with your use case, but I guess someone would need to add that kind of functionality to the home-manager service.