I need to find out how much garbage can be cleared when 'nix-collect-garbage -d' is run for a personal project but I haven't been able to find any answer about this on documentations and DDG.
I've tried 'du -sh /nix/store' but it would print the size everything in /nix/store however 'nix-collect-garbage -d' does not remove everything when it's executed so that's not gonna work. I've also tried executing "nix-store --gc --print-dead | grep '^/nix*'" ('--print-dead' produces output that which contains store paths that are not live and will not be used, with respect to roots) and then executing "stat -c '%s'" on each path ('stat -c "%s" $file_name' produces output containing the bytes of the concerned file in bytes) however that doesn't seem to work as well for some unknown reason as they all seem to add up to a few kilobytes (despite the actual amount that 'nix-collect-garbage -d' deletes being about 400MB).
I know that the code below is extremely shit but that's because that's not my main project but a separate script solely for trying to find out what I am doing wrong and how I can properly implement this in my main project.
Thanks for any help!
`#!/usr/bin/env bash
tmp() {
declare -a str byt
str=( $(nix-store --gc --print-dead 2>/dev/null | grep '/nix*') )
for garbage in "${str[@]}"; do
byt+=( $( stat -c '%s' $garbage ) )
done
total=0
for filesize in "${byt[@]}"; do
total=$(( $total + $filesize ))
done
convertedtotal="$(( ( $total / 1024 ) /1024 ))MB"
echo "$total"
echo "$convertedtotal"
}
tmp`
Some responses from people on other platforms that did not work perfectly:
"I had the same issue a couple months back, i asked claude back then and got: sudo nix-store --gc --print-dead 2>/dev/null | xargs -I{} du -s {} 2>/dev/null | awk '{sum += $1} END {printf "%.2f GB\n", sum/1024/1024}'"
And
"```
bytes=$(
nix-store --gc --print-dead |
xargs du -sb |
awk '{s+=$1} END {print s}'
)
numfmt --to=iec "$bytes"
some like this should work for you"
Both of them had one issue:
`$ nix-store --gc --print-dead | grep '^/nix*' | xargs du -sh | awk '{ print $1 }'
finding garbage collector roots...
determining live/dead paths...
8.0K
8.0K
8.0K
4.0K
1.6M
1.9M
8.0K
2.3M
8.0K
45M
4.0K
4.0K
8.0K
4.0K
4.0K
4.0K
684K
8.0K
8.0K
4.0K
8.0K
8.0K
7.7M
692K
4.0K
728K
8.0K
8.8M
344K
492K
4.0K
572K
8.0K
1.1M
4.0K
4.0K
8.0K
4.0K
8.0K
36K
8.0K
8.0K
8.0K
4.0K
4.0K
8.0K
# All of that is about 72MB.
$ nix-collect-garbage -d
removing old generations of profile /home/north/.local/state/nix/profiles/home-manager
removing old generations of profile /home/north/.local/state/nix/profiles/profile
finding garbage collector roots...
deleting garbage...
deleting '/nix/store/vdixm6r047a3rw1wx8pqsjh40nl886jj-kate-26.04.2.drv'
deleting '/nix/store/s5i0c135x2x5dz9ah01zxvl3prywqb30-kate-26.04.2.tar.xz.drv'
...
deleting '/nix/store/rivv4fh68mkqnc4v225mflmi3a9damcj-xfconf-4.20.0'
deleting '/nix/store/9nj1k063j54qfxzcm49dspwwl1sxhqs0-libxfce4util-4.20.1'
deleting unused links...
note: hard linking is currently saving 0.0 KiB
46 store paths deleted, 64.8 MiB freed`
Now what's strange is that 'nix-store --gc --print-dead' outputs these 46 paths (which add up to ~72MB) and 'nix-collect-garbage -d' deletes 46 paths but somehow, 64.8 MiB, which is about 68MB, is freed instead of 72MB. I tried to replicate this again and it worked, there's always some amount of inaccuracy. Of course, a few megabytes don't matter but this can create significant inaccuracies on systems with more cache, but this definitely is a lot better.
'nix-store --gc --print-dead' does that already and 'nix-collect-garbage --dry-run' prints only the number of paths that will be deleted and does not display the correct size of it either. I had tried it and it won't work here.