Get size of /nix/store efficiently

Hi,

I’d like to know the size of the complete /nix/store to decide whether to do GC when it gets over a threshold.

Currently I’m reading the nix DB to do that:

sqlite3 'file:/nix/var/nix/db/db.sqlite?readonly=true&immutable=true' 'SELECT SUM(narSize) FROM ValidPaths'

That works, but of course that’s not a supported API, and I’m ignoring the lock which I’m sure could lead to errors (maybe it would be possible to run this with the permissions and in the mount namespace of the nix daemon?).

The manual suggests this, but it’s very inefficient:

  · Show the size of the entire Nix store:
    
      | # nix path-info --json --all | jq 'map(.narSize) | add'
      | 49812020936

Is there a way to do the equivalent of the sqlite query through the nix CLI or in the nix language?

If not, would there be interest in adding such a feature?

What I’d ideally like is the same as the min-free option: https://nix.dev/manual/nix/2.24/command-ref/conf-file.html#conf-min-free

but as max-usage instead. But just having that sqlite query exposed would be sufficient to do it manually.

You could just do a blunt du -sh /nix/store. That will give you the disk space consumed by the nix store, in a human readable fashion, with a summary at the bottom.

Yes of course, but that’s also not efficient, it has to look at all the files in the store, except maybe on BtrFS, its similar to the nix path-info command.

It might also be possible to set up quotas on the filesystem to track the disk usage of /nix/store separately from the rest, but it’s quite complicated.

This actually makes me think that using the narSize probably does not take the nix store hardlink optimizations into account, so it could be an overestimate. Not sure if that’s tracked in the DB as well.

Exactly because ncdu takes such a long time on /nix, I do the opposite: run ncdu --exclude /nix -x / to get the size of everything but /nix in my root partition, and then subtract that from the total space used on my root partition (obtained by e.g. df -h /) :slightly_smiling_face:

1 Like