Find differences between generations

I was wondering if there is an (easy) way to find the differences between two generations, preferably the files that were used to build them.
I have a mini-Server with an N100 that crashes after a couple of hours on all but the one generation. The most notable difference I am aware of is that the generation that works is using the 6.6.64 LTS linux kernel. I tried using

boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_6;

but the resulting 6.6.88 LTS kernel does not fix the issue. So either something changed between 6.6.64 and 6.6.88 that broke everything, or it is some other change I made to my config. I’ll try a 6.1 LTS kernel next, but wanted to know if there is an easy way to check for other changes first.
I compared the state of my git repo before the Build-date of the working generation with my current config but nothing jumped out and I don’t pull a lot on the server.

PS: no unusual logs, no temp spike, no high usage. It looks like a RAM or CPU issue, but things run stable on one generation.

❯ nixos-rebuild list-generations
Generation   Build-date           NixOS version           Kernel   Configuration Revision  Specialisation
169 current  2025-05-18 15:47:37  25.05.20250501.f02fddb  6.6.88                           *
168          2025-05-14 19:14:49  25.05.20250501.f02fddb  6.12.25                          *
167          2025-05-14 18:18:40  25.05.20250501.f02fddb  6.12.25                          *
166          2025-05-13 20:17:59  25.05.20250501.f02fddb  6.12.25                          *
165          2025-05-11 01:05:09  25.05.20250508.dda3dcd  6.12.26                          *
164          2025-05-10 18:32:13  25.05.20250508.dda3dcd  6.12.26                          *
163          2025-05-10 18:14:15  25.05.20250508.dda3dcd  6.12.26                          *
162          2025-05-03 16:06:33  25.05.20250501.f02fddb  6.12.25                          *
161          2025-05-03 15:36:28  25.05.20250501.f02fddb  6.12.25                          *
160          2025-05-03 15:16:47  25.05.20250501.f02fddb  6.12.25                          *
159          2025-05-03 15:14:19  25.05.20250501.f02fddb  6.12.25                          *
158          2025-05-03 15:02:04  25.05.20250501.f02fddb  6.12.25                          *
157          2025-03-07 11:45:30  25.05.20241211.5d67ea6  6.6.64

config: Atman / NixOS Config · GitLab

Hi,

There is this thing called nvd which I think more or less does exactly that. It is integrated into nh which is handy.

Edit: There is also dix which seams to be nvd but faster.

that looks exactly like the tool I was looking for.
Thank you so much <3

1 Like

Nix also has a built-in command for this: nix store diff-closures - Nix Reference Manual

1 Like

I use the following nushell function to provide some convenient formatting over this…

def nsdc [
    before: path = /run/booted-system
    after: path = /run/current-system
]: nothing -> table {
  ^nix store diff-closures $before $after
  | ansi strip | lines
  | parse -r '^(?<pkg>[\w\.-]+): ?(?:(?<before>.+) → (?<after>.+?)),?? ?(?<size>[+-][\d\.]+ KiB)?$'
  | update before { str replace -a ", " "\n" }
  | update after  { str replace -a ", " "\n" }
  | update size {try { into filesize } | default 0b}
  | update pkg {
    |row| [
      (if ([linux nixos-system firefox mutter gnome-shell] | any { $row.pkg starts-with $in }) {ansi y})
      (if $row.before == ∅ and $row.size > 0b {ansi i})
      (if $row.after  == ε and $row.size == 0b {ansi d})
      (if $row.after  == ∅ {(ansi s) + (ansi d)})
      $row.pkg
      (ansi reset)
    ] | str join
  }
  | rename -c {before: ($before | path basename), after: ($after | path basename)}
}

Which (for example after the current update I just took) gives me a nice table of data I can use:

pkg booted-system current-system size
firefox 138.0.3 138.0.4 14.4 kB
firefox-unwrapped 138.0.3 138.0.4 121.0 kB
flatpak 1.16.0 1.16.1 245.2 kB
initrd-bin ε 128.0 kB
initrd-linux 6.12.28 6.12.29 -8.8 kB
initrd-udev ε 44.7 kB
ipxe 1.21.1-unstable-2025-05-07 1.21.1-unstable-2025-05-16 0 B
libphonenumber 9.0.3 9.0.5 0 B
linux 6.12.28
6.12.28-modules 6.12.29
6.12.29-modules -14.1 kB
lix 2.94.0-dev-pre20250518-8fa0363 2.94.0-dev-pre20250520-4f433a6 -936.0 kB
nixos-system-oenone 25.11.20250518.292fa7d 25.11.20250520.2795c50 0 B
python3.12-jc 1.25.4 1.25.5 36.7 kB
rclone 1.69.1 1.69.2 36.6 kB
v4l2loopback 0.13.2-6.12.28 0.13.2-6.12.29 0 B
vscode-extension-cweijan-vscode-database-client2 8.3.2 8.3.3 14.1 kB
vscode-extension-jnoortheen-nix-ide 0.4.16 0.4.18 0 B
vscode-extension-ms-python-python 2025.7.2025051601 2025.7.2025052004 65.5 kB
vscode-extension-rust-lang-rust-analyzer 0.3.2457 0.3.2466 -193.4 kB
zfs-kernel 2.3.2-6.12.28 2.3.2-6.12.29 0 B

or just let it be rendered on screen for review:

Note, however, the evil regex. It works, but there’s no particular guarantee that nix won’t change that output or that it covers all cases, even though I haven’t seen any problems. The recent lix release adds json output for this data, which is nicer - this version works with either, at least for now.

2 Likes