Store, profiles, and GC on Linux
Store, profiles, and GC on Linux
Goal: Operate /nix/store confidently on Fedora: see what a profile is, what keeps paths alive (GC roots), and how to garbage-collect without deleting tomorrow’s work.
This is the same store model as NixOS—only the set of roots differs (no bootloader generations yet).
Why this chapter matters
On Fedora, nothing forces you to be declarative. The fastest way to recreate “npm global hell” is:
nix profile install nixpkgs#tool-a
nix profile install nixpkgs#tool-b
# …six months, no locks, no notes…Learn roots early and you will treat profiles as a small personal toolkit and flakes as the real project SoT—exactly the habit NixOS rewards.
Store anatomy (quick ops view)
ls /nix/store | head
nix path-info nixpkgs#hello
nix path-info -r $(nix build nixpkgs#hello --print-out-paths) | wc -l| Idea | Meaning |
|---|---|
| Store path | /nix/store/<hash>-name content-addressed build result |
| Closure | Path + all runtime references |
| GC root | A pointer that says “do not delete this closure” |
| Profile | User (or system) generation of linked apps—a GC root |
Diagram:
~/.nix-profile ──► /nix/var/nix/profiles/per-user/$USER/profile
│
▼
generation-42-link ──► store paths
Profiles: what they are for
Inspect
nix profile list
readlink -f ~/.nix-profile
ls -l /nix/var/nix/profiles/per-user/$USER/ | tailInstall / remove (modern)
nix profile install nixpkgs#ripgrep nixpkgs#fd
rg --version
fd --version
nix profile list
nix profile remove … # use the index/name from list — check `nix profile remove --help`Upgrade
nix profile upgrade
# or reinstall from a pinned flake input instead of floating nixpkgs#Bridge habit: keep the imperative profile thin (editor, rg, direnv). Put project tools in devShells. On NixOS you will barely need nix profile at all.
Other roots you will meet
| Root kind | Example | Created by |
|---|---|---|
| User profile | ~/.nix-profile |
nix profile |
| Result symlink | ./result |
nix build in a directory |
| direnv | nix-direnv GC roots | use flake + allow |
| Home Manager | HM profile generations | home-manager switch |
| NixOS system | /run/current-system |
nixos-rebuild (later) |
# List roots (classic tool still useful)
sudo nix-store --gc --print-roots 2>/dev/null | head -50
# or
nix-store --gc --print-roots 2>/dev/null | head -50Find who pins a path:
# After building hello to ./result
nix build nixpkgs#hello
nix-store --query --roots $(readlink -f result) || trueGarbage collection
Safe everyday
# Delete unreachable paths
nix store gc
# or
nix-collect-garbageDelete old profile generations
# User profiles / HM generations (read manpages for exact flags on your version)
nix-collect-garbage -d
# Older alias many still use:
# nix-env --delete-generations oldnix-collect-garbage -d is aggressive on generations. Fine on a lab account; think twice if you rely on rolling back HM quickly.
Disk pressure playbook
df -h /nix
nix path-info -Sh /nix/var/nix/profiles/per-user/$USER/profile 2>/dev/null || true
# Find large paths (nix-tree if installed)
nix run nixpkgs#nix-treeOptional: set free-space goals in nix.conf (daemon may need system file):
min-free = 1073741824
max-free = 5368709120
Channels vs flakes (on Fedora)
Fedora users sometimes enable channels by habit. This book’s default is flakes + locks.
| Approach | Pinning | Team repro |
|---|---|---|
Channels + nix-env |
Floating | Weak |
nix profile install nixpkgs#foo without lock |
Floating nixpkgs | Weak |
Project flake.lock |
Strong | Strong |
| HM flake input lock | Strong | Strong |
# Prefer explicit flake refs in projects
nix flake metadata .You may still see nix-channel on old blog posts—literacy only (Classic CLI).
Binary caches
Default substitutes (cache.nixos.org) keep Fedora+Nix usable.
nix show-config | rg substituter
# First download of a big stdenv is slow; later hits cacheLater: Cachix/Attic in packaging/ops parts. On a laptop, don’t disable substitutes “for purity cosplay” unless studying FODs.
Worked lab: profile vs shell
cd ~/lab/nixos-book/nix-on-linux
mkdir -p store-lab && cd store-lab
# A) Ephemeral — disappears when shell exits (no profile pollution)
nix shell nixpkgs#jq --command jq --version
# B) Build root in cwd
nix build nixpkgs#jq
ls -l result
./result/bin/jq --version
# C) Profile (persistent)
nix profile install nixpkgs#jq
command -v jq
# Clean lab build root
rm -f result
nix store gcWrite three sentences in your journal: what remained after each of A/B/C.
Checkpoint
- You can define store path, closure, GC root
nix profile listis intentional and small
- You can find roots and run
nix store gcsafely
- You prefer flake locks over channels for projects
Further depth
- Store and closures
- Daily CLI and devShells
- NixOS-side roots: Rebuild and generations