Skip to content

Incremental GC#15829

Open
tomberek wants to merge 3 commits into
NixOS:masterfrom
tomberek:pr/fast-gc-rounds
Open

Incremental GC#15829
tomberek wants to merge 3 commits into
NixOS:masterfrom
tomberek:pr/fast-gc-rounds

Conversation

@tomberek
Copy link
Copy Markdown
Contributor

Motivation

Slow GC on a Hydra machine.

Context

Has some similarities to #14725.

The main idea is to run a SQL query to find the dead leaves and quickly GC those. This creates a GC that is not complete, but incremental and quick. Also allows using registration time because this is available in the sqlite to limit what is cleaned up.

Subsequent improvements are to make deletePath just move the contents into /nix/store/.gc-trash atomically+quickly and allow for releasing the GC lock and unlinking in another thread, rather than being forced to slowly recursively unlink. Also looked at using io_uring for faster /nix/store/.links cleanup, it works and is pretty fast, but unsure if we want the added complexity.

Code written by Claude.... fair amount of iteration and cajoling to get the output right.

Limitation and next steps

This calls SQL directly and works only with a local store. Support for remote/daemon requires updating the daemon protocol to support the new options or to define a new operation.

@github-actions github-actions Bot added documentation new-cli Relating to the "nix" command labels May 10, 2026
@tomberek tomberek force-pushed the pr/fast-gc-rounds branch from 0bf2a4d to cc018d6 Compare May 11, 2026 00:27
tomberek added 3 commits May 10, 2026 20:40
The fast GC was comparing base32 hashes (from StorePath::hashPart()) against
base16 hashes (from ValidPaths.hash column in SQL), causing the comparison
to always fail. This meant NO roots were being protected, and rooted paths
were incorrectly deleted!

Fix: Extract hash part from the path column (which is already in base32 format)
instead of using the hash column (which is in base16 format).

This is a critical correctness bug that would cause data loss.

Testing: Verify that paths with roots in /nix/var/nix/gcroots are not deleted:
  ls -l /nix/var/nix/gcroots/auto/ | head
  nix store gc --prune-older-than 7200000 --dry-run
  # Should NOT list paths that have roots pointing to them
@tomberek tomberek force-pushed the pr/fast-gc-rounds branch from cc018d6 to fb98a61 Compare May 11, 2026 01:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation new-cli Relating to the "nix" command

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant