How can I protect a system generation from garbage collection?

Body:

I have a NixOS system with multiple generations and I want to protect generation 25 from being garbage collected, as it has a working configuration that I need to keep available for booting.

Current situation:

  • Running generation 25 (selected via GRUB): /nix/store/l5gyyp1s2cm0yc4ph8sxjpnnl1bsrb67-nixos-system-p3-24.11.20250412.26d499f
  • Current profile points to generation 31
  • Generation 25 has working NVIDIA drivers, while newer generations have issues

What I’ve tried:

# This fails - selector doesn't work for system generations
sudo nix-env --profile /nix/var/nix/profiles/system --set-flag keep true 25

# This also fails - store path not recognized
sudo nix-env --profile /nix/var/nix/profiles/system --set-flag keep true /nix/store/l5gyyp1s2cm0yc4ph8sxjpnnl1bsrb67-nixos-system-p3-24.11.20250412.26d499f

Questions:

  1. What’s the correct way to prevent a specific NixOS system generation from being garbage collected?
  2. Should I use nix-store --add-root or is there a nixos-specific method?
  3. Is there a difference between protecting user profile generations vs system generations?

I need to keep this generation available in GRUB for fallback purposes since newer generations introduced driver regressions.

Any guidance would be appreciated!

I think you may want to add a symlink from /nix/var/nix/profiles/system-25-link to /nix/var/nix/gcroots/

There’s no clean command to mark it protected?:wink:

I told ya what I know =) Never knew there was any other way…

Sure;) Seems to work. Thanks.

1 Like

I don’t think there’s anything better than adding a gc root yourself. nixos-rebuild doesn’t manage generations at all, there’s only a subcommand to list them and that is a recent addition.

Maybe nixos-rebuild-ng will improve on this.

How does a manual GC root interact with nix-collect-garbage --delete-older-than <period>?

IIRC, you can somehow tag your generation with a name and they won’t get garbage collected. (to be verified!)

Not having tried it, but in my mental model I would worry that a manual gcroot would protect /nix/store/<hash>-<hostname>-profile from GC, but still allow the symlink /nix/var/nix/profiles/system-#-link to be deleted by --delete-older-than. If I understand correctly, the effect then being that on the next switch-to-configuration switch, the boot entries get deleted from the bootloader even if the profile technically exists in /nix/store.

(also to be verified, by someone who wants this feature and is willing to investigate)

In theory if you really wanted to preserve a boot entry, you could probably create it manually through manipulation of /boot in various ways, using a gcroot to preserve the /nix/store path.

1 Like