NixOS System Generations: Atomic Rollbacks That Actually Work
NixOS system generations give you atomic, bootloader-integrated rollbacks. A kernel update breaks Wi-Fi? Reboot, pick the previous generation, run nixos-rebuild switch --rollback. Done. But generations consume disk space and don't touch user data — here's how to manage both.
08 Aug 2025, 15:40 UTC

The Problem: Updates Break Things
You apply a system update, reboot, and Wi-Fi disappears. The new kernel dropped a firmware blob your card needs. On most distributions you're stuck: chroot from a live USB, downgrade packages manually, pray the package manager doesn't fight you. NixOS handles this differently. Every nixos-rebuild switch or boot creates a generation — a complete, immutable system closure (kernel, initrd, all packages, configuration) stored under /nix/var/nix/profiles/system-<N>-link and registered in your bootloader. Rollback is a boot-menu selection away.
How Generations Work
When you run nixos-rebuild switch, Nix builds the new system closure in /nix/store, creates a symlink system-<N>-link pointing to it, and updates the bootloader (systemd-boot or GRUB) with a new menu entry. The previous generation stays untouched. No packages are overwritten in place because the store is content-addressed and immutable.
To see your generations:
nixos-rebuild list-generations
# Example output:
# 42 2026-09-28 14:22 (current)
# 41 2026-09-27 09:15
# 40 2026-09-26 18:03
Each line shows generation number, timestamp, and kernel version. The current generation is marked. Bootloader entries mirror this list — run bootctl list (systemd-boot) or grep menuentry /boot/grub/grub.cfg (GRUB) to confirm.
Worked Example: Kernel Update Breaks Wi-Fi
You update, reboot, and iwctl shows no adapter. The new kernel's linux-firmware package omitted your driver. Here's the recovery:
- Reboot. At the systemd-boot menu (or GRUB), select the previous generation (e.g., "NixOS 24.11 (generation 41)").
- System boots with the exact prior kernel, userspace, and config. Wi-Fi works.
- Log in. Make the good generation the default for next boot:
This flips thesudo nixos-rebuild switch --rollbacksystemsymlink to generation 41 and regenerates the bootloader. No rebuild, no download. - Now fix the root cause: add the missing firmware to your
configuration.nix(e.g.,hardware.enableRedistributableFirmware = true;or a specificlinux-firmwareoverride), thensudo nixos-rebuild switchto create a new, working generation 43.
Total downtime: one reboot. No live USB, no chroot, no package-manager surgery.
Trade-offs and Limits
Disk Space
Each generation is a full system closure. A typical desktop accumulates 5–15 GB per generation; servers with many services can exceed 20 GB. The store grows until garbage collection runs. NixOS enables a systemd timer (nix-gc.service) that runs nix-collect-garbage -d periodically, but by default it keeps only the current and previous generation. If you want more history, tune nix.gc.options in configuration.nix (e.g., --keep-outputs, --keep-derivations for build caches) or run manual cleanup:
# Dry-run first — verify current and previous generations are NOT listed
nix-collect-garbage --dry-run -d
# Actual cleanup (requires root)
sudo nix-collect-garbage -d
To prune older profile entries explicitly without touching store paths:
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system
User Data Is Not Rolled Back
Generations cover the system closure only: kernel, packages, system config. Your home directory, databases in /var/lib, logs, and any mutable state remain untouched. If a schema migration runs during the bad generation, rolling back the system won't revert the database. Pair NixOS rollbacks with filesystem snapshots (btrfs/ZFS) or application-level backups for full state recovery.
Common Pitfalls
- Garbage collection without care:
nix-collect-garbage -dwithout--delete-older-thancan remove the fallback generation if it's not current or previous, leaving no rollback target. - GRUB manual edits lost: On GRUB systems, boot menu entries are regenerated on every rebuild. Manual
/boot/grub/grub.cfgedits will be overwritten. - Imperative installs don't create generations:
nix-env -iornix profile installaffect user profiles, not the system profile. They are not rolled back bynixos-rebuild --rollback. - Encrypted root with separate
/boot: For rollback to work reliably on LUKS, the kernel and initrd must be on an unencrypted/bootpartition accessible to the bootloader.
Verify Your Setup
Before you need a rollback, confirm it works:
nixos-rebuild list-generations— lists all generations with dates.bootctl listorgrep menuentry /boot/grub/grub.cfg— confirms bootloader entries exist.nixos-rebuild switch --rollback --dry-run— shows which generation would become default without changing boot order.- Estimate per-generation store usage:
nix path-info -Sh /nix/var/nix/profiles/system-*-link | awk '{sum+=$1} END {print sum/1024/1024 " GiB"}' nix-collect-garbage --dry-run -d— verify current and previous generation paths are absent from the deletion list.
These commands run as root (or with sudo) on the target NixOS machine. No special permissions beyond standard administration.
Closing: Make Rollback a Habit
NixOS generations turn system updates from irreversible events into reversible checkpoints. The mechanism is built on the store's immutability and bootloader integration — no extra tooling, works identically on x86_64, aarch64, and other supported architectures. Keep at least two generations, monitor /nix/store growth, and pair with filesystem snapshots for user data. Next time an update breaks something, you'll reboot, pick the previous entry, and keep working while you fix the config. That's the point.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.