AutoUpdate and GC behavior

Hello NixOS community!

On my NixOS desktop I use a combination of sudo nixos-rebuild switch --upgrade and sudo nix-collect-garbage --delete-older-than 30d to update the system, garbage collect, and update the boot menu to both add and remove generations.

I had assumed that the declarative “configuration.nix” equivalent would be:

system.autoUpgrade = {
 enable = true;
 dates = "*-*-* 04:00:00";
 persistent = true;
 allowReboot = true;

nix.gc = {
 automatic = true;
 persistent = false;
 dates = "daily";
 options = "--delete-older-than 30d";

Based on the output of journalctl -u nix-gc.service the garbage collect is running, and I can see that the boot menu is getting updated with new generations, however the old ones aren’t getting removed based on my experiments so far.
I have tried searching for an answer and browsed the systemd-boot NixOS options, but I haven’t found a solution yet.

I was hoping to find out if I’m doing something wrong, or if there’s some incantation I can add to my “configuration.nix” file that would remove the old garbage collected boot entries automatically.

Thank you for your time!

1 Like

Maybe I spoke too soon.

For days now the output of sudo nix-env -p /nix/var/nix/profiles/system --list-generations showed 2023-06-06 as the oldest generation:

  57   2023-06-06 04:01:09
  58   2023-06-14 12:22:55
  59   2023-06-24 04:09:45
  60   2023-07-08 12:21:21
  61   2023-07-10 04:02:38
  62   2023-07-10 11:07:42   (current)

However I checked today and it changed overnight to:

  58   2023-06-14 12:22:55   
  59   2023-06-24 04:09:45   
  60   2023-07-08 12:21:21   
  61   2023-07-10 04:02:38   
  62   2023-07-10 11:07:42   
  63   2023-07-12 04:01:19   
  64   2023-07-13 04:01:42   
  65   2023-07-14 04:01:56   
  66   2023-07-14 14:02:59   
  67   2023-07-15 04:00:32   (current)

So clearly the oldest entry (#57) was removed, it just happened about 9 days after I expected it to happen.

Do you turn off the machine? As the GC timer is not persistent (according the snippet you have posted) that could be then a reason for what you observe . Non persistnt timers are not done if the timeslot was missed, if the machine was turned off

Thank you for your response!

No, the machine is a VM that has been up for 21 days (not including reboots) mostly to confirm my expectations regarding auto update and garbage collect.

You may want to take a look at min-free and max-free nix.conf options too

Thank you for the suggestion, however I really prefer the consistency of knowing how many generations I have vs managing by available storage.

I’ll leave my configuration the way it is and will continue monitoring it for now. Maybe I’ll eventually see what’s causing the delay in removing boot entries, however I’m content as long as it does removed them and the list doesn’t get too long.

Thank you!

there is a wrinkle in the definition of the “older than” parameter. It works based on when the generation was active, not when it was created, so that you can go back to what you were running at that time. So, if you delete older than 10 days, but go 11 days between updates, that generation will be ~21 days old before getting deleted.

Not sure if this is a factor in your case, but it may be


That wouldn’t automatically remove previous generations as they are linked somewhere in /nix/var/nix/profiles IIRC :slight_smile: but this could delete derivations pulled from a nix-shell or nix-build.

I think that perfectly explains the delay I’m seeing, and why I initially thought the garbage collect wasn’t working correctly.

The generation was created 2023-06-06
The next generation was created 2023-06-14 (so the previous generation was in use up to this date)
The generation created on 2023-06-06 was garbage collected on 2023-07-15
2023-06-06 + 9 days in use + 30 day gc delay = 2023-07-15 (when I saw it getting removed)

Mystery solved, Thank you!

1 Like

I see, I didn’t realize that they have different uses. I imagine the normal garbage collect still would delete nix-shell and nix-build derivations though?

1 Like