Take Out the Rubbish
New Nix users are often surprised when deleting a file, uninstalling a package, or switching generations does not free disk space. The Nix store is not a temp folder that forgets what you touched. It is a graph of build artifacts, and cleanup is driven by graph reachability, not intuition.
Nix keeps a store path alive as long as it is reachable from a garbage collection root. If something still points at a path, that path is live and cannot be deleted. Common roots include:
- current system profiles
- user profiles
- old generations
- symlinks like
result - explicitly registered roots
- development environments that still reference store paths
This is why Nix can offer safe rollbacks and reuse, and also why disk usage grows when roots accumulate.
If Nix keeps something you expected to be gone, the answer is usually simple: somewhere, something still points at it.
One frequent culprit is the result symlink created by
nix build:
nix build .#package
ls -l resultThat symlink points into /nix/store. As long as it
exists, the target is considered live. Remove it when you no longer need
it:
rm resultIf nothing else references that path, it becomes eligible for garbage collection.
After checking roots, run garbage collection:
nix-collect-garbageUseful options:
nix-collect-garbage -dremoves old profile generations.nix-collect-garbage --delete-older-than 30dremoves generations older than the given period, while preserving generations active during that window.
You can also automate cleanup so maintenance does not depend on memory:
# In your nix.conf or configuration.nix
gc = {
automatic = lib.mkForce true;
dates = lib.mkForce "weekly";
options = lib.mkForce "--delete-older-than 7d";
};
# Minimum free space before triggering GC
min-free = builtins.toString (30 * 1024 * 1024 * 1024); # 30 GB
min-free-check-interval = lib.mkForce 1;automatic = trueenables scheduled garbage collection.dates = "weekly"runs it weekly.options = "--delete-older-than 7d"trims old generations.min-freesets a floor for available disk space.min-free-check-intervalcontrols how often free space is checked.
Sometimes you also inherit dangling symlinks that point into
/nix/store from old builds or manual operations. These do
not always point to valid targets, but they are worth finding and
cleaning up to keep your workspace tidy:
find ~ -type l -lname '/nix/store/*' \
! -exec test -e {} \; -printIf disk usage is not dropping, run this quick checklist before assuming GC is broken:
- Is there a
resultsymlink or another store symlink still present? - Are old generations still retained?
- Does a user or system profile still reference the package?
- Is a development shell or tool registering roots?
- Did you run garbage collection after removing roots?
Nix is conservative on purpose: it deletes only unreachable paths. That safety-first behavior is what keeps rollbacks reliable, even when it occasionally feels stubborn.