OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 018

NixOS generation management and garbage collection

Understand the generation lifecycle through inspection, activation, history removal, and storage reclamation.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSNixOS system foundations and configuration ↗
About 5 min readStart reading

Generation management in NixOS mainly uses three command families: nixos-rebuild, nix-env, and nix-collect-garbage. The core operations are listing, switching, deleting, and cleaning up. Combined with automatic maintenance options in configuration.nix, they can run unattended. The following are maintenance examples; confirm the target profile and required rollback window before running them.

1. Overview of the generation lifecycle#

flowchart LR
    A["修改 configuration.nix<br/>或 flake.nix"] --> B["nixos-rebuild switch"]
    B --> C["生成新 Generation<br/>旧版本保留在 /nix/store"]
    C --> D{系统是否正常?}
    D -- 正常 --> E["继续使用"]
    D -- 异常 --> F["nixos-rebuild switch --rollback<br/>或 GRUB 菜单选择旧世代"]
    F --> E
    E --> G["定期清理旧世代<br/>nix-collect-garbage"]
    G --> H["nix-store --gc<br/>回收未引用的 store 对象"]

switch/boot can record a new generation when updating the system profile. Running only build or test does not establish a new system profile generation. Old generations are generally retained until manual or automatic maintenance deletes them. The ability to roll back depends on which profiles and outputs remain. The corresponding /nix/store paths are actually freed only after generations are explicitly deleted and garbage collection runs.

2. Common commands at a glance#

Operation Command Notes
List all system generations sudo nixos-rebuild list-generations Included in newer NixOS versions; provides the clearest output
List all system generations (general method) sudo nix-env --list-generations --profile /nix/var/nix/profiles/system General interface for traditional profiles
List generations of the current user environment nix-env --list-generations User-level profile
Roll back to the previous generation sudo nixos-rebuild switch --rollback Switches immediately without a reboot
Switch to a specific generation (for example, 204) First run sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation 204, then sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch Changing the profile and activating it are separate steps
Delete specific generations sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations 205 206 Deletes generations 205 and 206
Keep only the latest 5 sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations +5 +N means retain the latest N generations
Delete generations older than 30 days sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations 30d Age-based cleanup
Delete old generations and reclaim space sudo nix-collect-garbage -d Deletes all old generations + GC; the most common approach
Clean up by age and reclaim space sudo nix-collect-garbage --delete-older-than 30d Retains the last 30 days; a safer approach
Collect only unreferenced store objects sudo nix-store --gc Does not delete generations; removes only unreferenced paths
Preview what would be deleted sudo nix-store --gc --print-dead Lists "dead" objects without actually deleting them
Roll back through GRUB at boot Select "NixOS - All configurations" from the boot menu Choose any historical generation to boot

Tip: nix-collect-garbage -d is equivalent to first running nix-env --delete-generations old on the profiles the tool finds, then running nix-store --gc. Afterward, you cannot roll back to deleted generations.

3. Freeing space in /nix/store#

1. Standard two-step cleanup

# 第一步:删除 14 天前的系统世代
sudo nix-env --delete-generations --profile /nix/var/nix/profiles/system 14d
# 第二步:只回收未引用的 store 对象,不再扩大历史删除范围
sudo nix-store --gc

This procedure limits history deletion to the specified system profile. Delete generations before running GC; otherwise, packages referenced by those generations will not be collected.

2. Optimize storage (deduplicate with hard links)

sudo nix-store --optimise

Deduplicate identical store file contents using hard links. Space savings depend on how much content is duplicated; this can be run regularly alongside GC.

4. Configure automatic maintenance in configuration.nix#

Add these options to /etc/nixos/configuration.nix and rebuild to enable automatic cleanup without running commands manually:

{ config, pkgs, ... }:
{
  # 限制 GRUB 启动菜单中保留的世代数量(建议 10-20)
  boot.loader.grub.configurationLimit = 20;
  # 自动垃圾回收
  nix.gc = {
    automatic = true;
    dates = "weekly";              # 每周执行,也可用 "03:30" 指定时间
    options = "--delete-older-than 30d";  # 只删 30 天前的世代
  };
  # 自动优化存储(硬链接去重)
  nix.settings.auto-optimise-store = true;
  # 设置构建时尝试自动 GC 的可用空间阈值(不是 store 容量硬限制)
  nix.extraOptions = ''
    min-free = ${toString (5 * 1024 * 1024 * 1024)}
    max-free = ${toString (10 * 1024 * 1024 * 1024)}
  '';
}

nix.gc.automatic is the officially recommended approach to prevent /nix/store from growing without bound. boot.loader.grub.configurationLimit limits the number of GRUB menu entries at the source, keeping the boot list from becoming too long.

5. Advanced tips#

1. Simplify operations with nh

nh (nix helper) is a popular community wrapper. It provides friendlier commands such as nh os switch and nh os generations, and can display a configuration diff after rebuilding.

2. The newer nix commands

The new CLI provides the nix profile command family for managing generations:

sudo nix profile history --profile /nix/var/nix/profiles/system          # 查看历史
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d  # 清理 7 天前

This pattern is common in community configuration repositories.

3. Roll back when the system cannot boot

Even if the system cannot reach the desktop, NixOS retains a "NixOS - All configurations" submenu in GRUB by default. It lists historical generations that have not been deleted and fall within the boot-menu retention limit. Select one to return to a previous working state; this is the last safety net.

4. Safe cleanup recommendations

  • Before running nix-collect-garbage -d, confirm that the current generation is stable, because deleted generations cannot be used for rollback.
  • On production servers, prefer --delete-older-than 30d over -d to retain a rollback window.
  • After a major version upgrade, verify operation and the rollback procedure before cleaning up according to your retention policy. Limiting menu entries does not automatically delete profile history or free all store space.

Together, these commands and settings cover most needs from everyday rollback to long-term disk maintenance: inspect status with nixos-rebuild list-generations, use --rollback in emergencies, clean up regularly with nix-collect-garbage --delete-older-than, and add nix.gc.automatic as an automatic fallback.


References & further reading

  1. NixOS manual ↗
  2. Nix language manual ↗
  3. Nix: garbage collection and profile scope ↗
  4. Nix: wipe-history ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

NixOS system foundations and configuration

  1. 01NixOS: the foundations of a declarative system
  2. 02Installing NixOS: installation media, partitions, and initial configuration
  3. 03NixOS configuration basics: options and modules
  4. 04Managing a system with Flakes and Home Manager
  5. 05The NixOS command line: old and new interfaces and everyday maintenance
  6. 06NixOS generation management and garbage collection
  7. 07Specialisation: multiple configuration variants in one generation
  8. 08If configuration is reproducible, why do apps still forget?
CONTINUE READING / NEXT ARTICLESpecialisation: multiple configuration variants in one generation

Declare variants under a base configuration and distinguish runtime activation from changes that require a reboot.