NIX-STORE-OPTIMISE(1)
π nix-store --optimise(1) π
General Commands Manual β yes bestie, it's a real manual page, and it's lowkey iconic.
β¨ NAME β¨
nix-store --optimise β reduce disk space usage ποΈπ
πΈ SYNOPSIS πΈ
nix-store --optimise
π¦ DESCRIPTION π¦
Okay so the --optimise operation is the one that makes your Nix store β¨skinnierβ¨. It reduces Nix store disk space usage by finding identical files in the store and hard-linking them to each other. The way it typically does this? It reduces the size of the store by something like 25-35%. No cap, that's a whole glow-up for your SSD. π₯
Only regular files and symlinks get hard-linked in this manner β nothing else is out here getting linked, periodt.
So when are two files considered identical? Bestie, it's about the Nix Archive (NAR) serialisation: that is, regular files must have the same contents and permission (executable or non-executable), and symlinks must have the same contents. Same NAR vibe = same file, fr fr. π«Ά
After completion, or when the command is interrupted, a report on the achieved savings is printed on standard error. So go ahead and look at stderr, that's where the receipts live. π
Use -vv or -vvv to get some progress indication. More v's = more gossip about what's happening. π
π OPTIONS π
The following options are allowed for all nix-store operations, but may not always have an effect. (like, they're always invited to the party, but sometimes they just vibe in the corner)
--add-rootpath
Causes the result of a realisation (--realise and --force-realise) to be registered as a root of the garbage collector. ποΈπ«
path will be created as a symlink to the resulting store path. In addition, a uniquely named symlink to path will be created in /nix/var/nix/gcroots/auto/. For instance,
$ nix-store --add-root /home/eelco/bla/result --realise ...
$ ls -l /nix/var/nix/gcroots/auto
lrwxrwxrwx 1 ... 2005-03-13 21:10 dn54lcypm8f8... -> /home/eelco/bla/result
$ ls -l /home/eelco/bla/result
lrwxrwxrwx 1 ... 2005-03-13 21:10 /home/eelco/bla/result -> /nix/store/1r11343n6qd4...-f-spot-0.0.10
Thus, when /home/eelco/bla/result is removed, the GC root in the auto directory becomes a dangling symlink and will be ignored by the collector. It simply stops being perceived. ghosted, honestly. π«₯
β οΈ Warning β οΈ
Note that it is not possible to move or rename GC roots, since the symlink in the auto directory will still point to the old location. So don't try it!! The symlink remembers where you used to live and it is NOT updating its contact info. π
If there are multiple results, then multiple symlinks will be created by sequentially numbering symlinks beyond the first one (e.g., foo, foo-2, foo-3, and so on). Cute little numbered besties, one through infinity. π
π COMMON OPTIONS π
okay so like, most Nix commands accept this same lil squad of command-line options β think of them as the shared group chat that every Nix tool is in π«Ά
--helpβ prints out a lil summary of the command syntax and then dips. bye bestie π--versionβ prints the Nix version number on standard output and exits. that's it, that's the tweet π--verbose/-vβ turns the volume UP on the diagnostic messages that get printed to standard error. and here's the tea, bestie: for every Nix operation, whatever lands on standard output is well-defined β all the diagnostic noise goes to standard error</>, never to standard output. fr fr.
this option can be given more than once, and rn the vibes scale goes like this:
- 0 βErrors onlyβ β only tells you why the Nix invocation flopped. painful but necessary π
- 1 βInformationalβ β the useful stuff about what Nix is actually doing. this is the default, it's giving reliable π
- 2 βTalkativeβ β more informational messages. she's chatty now π
- 3 βChattyβ β even MORE informational messages. okay she's really talking π
- 4 βDebugβ β prints debug information. nerdy era π
- 5 βVomitβ β prints vast amounts of debug information. and yes, that is genuinely the name, no cap π©Έ
--quietβ turns the volume DOWN on diagnostic messages printed to standard error. it's literally the inverse option to-v/--verbose. can also be given multiple times β same verbosity levels list as above, just walked backwards π¦--log-formatformat β changes the output of the log format, where format is one of these iconic options:rawβ the raw format, exactly as outputted bynix-build. plain, unbothered, moisturised πΈinternal-jsonβ outputs the logs in a structured manner. slay, structured queen β¨
β οΈ Warning β while the schema itself is relatively stable, the format of the error-messages (namely of the msg-field) can change between releases. so don't you dare parse it and then act surprised, bestie π€
barβ only shows a progress bar during the builds. minimalism, we love her πbar-with-logsβ shows the raw logs, with the progress bar chillin' at the bottom. best of both worlds π
--no-build-output/-Qβ by default, whatever the builders write to standard output and standard error gets echoed to the Nix command's standard error. this option suppresses that behaviour. but β and this is important β the builder's standard output and error are always written to a log file inprefix/nix/var/log/nix. nothing is lost, it's just not being yelled at you π--max-jobs/-jnumber β sets the max number of build jobs Nix will run in parallel. sayautoand it'll use however many CPUs the system has. the default comes from themax-jobsconfiguration setting, which itself defaults to1. a higher number is useful on SMP systems or when you wanna exploit I/O latency, i.e. when your machine is just sitting there waiting and you're like "girl, do something" π
setting it to 0 disallows building on the local machine β which is exactly what you want when builds should only happen on remote builders. main character remote-only era π
--coresβ sets the value of theNIX_BUILD_CORESenvironment variable in the invocation of builders. builders can use that variable however they please to control max parallelism. like, in Nixpkgs, if the derivation attributeenableParallelBuildingis set totrue, the builder passes the-jNflag to GNU Make. defaults to the value of thecoresconfiguration setting if it's set, or1otherwise. and the value0means the builder should use all available CPU cores in the system. go big or go home π₯--max-silent-timeβ sets the max number of seconds a builder can go without producing any data on standard output or standard error. default comes from themax-silent-timeconfiguration setting.0means no time-out β she can be silent forever, which is honestly a mood π--timeoutβ sets the max number of seconds a builder can run. default comes from thetimeoutconfiguration setting.0means no timeout. go ahead, take your time, queen β³--keep-going/-kβ keeps going even when builds fail, to the greatest extent possible. so if building an input of some derivation fails, Nix will still build the other inputs β just not the derivation itself. without this option, Nix stops the moment any build fails (except for builds of substitutes) and might even kill builds that are in progress, in the case of parallel or distributed builds. brutal π--keep-failed/-Kβ says that if a build fails, the temporary directory where the build happened (usually somewhere in/tmp) should not be deleted. the path of the build directory gets printed as an informational message. forensic girlie behaviour, respect π--fallbackβ whenever Nix tries to build a derivation where substitutes are known for each output path, but realising those output paths through the substitutes fails, it falls back on building the derivation itself.
the most common case where this is a lifesaver is when we've registered substitutes to do binary distribution from, say, a network repository. if the repo is down, realising the derivation will fail. with this option, Nix just builds the derivation instead. so installation from binaries falls back on installation from source β¨ this is not the default, because honestly it's generally not desirable for a transient failure in getting substitutes to trigger a whole build from source β with all the resource consumption that comes with it. like, no thank you? π
--readonly-modeβ when this is on, no attempt is made to open the Nix database. most Nix operations do need database access, so those operations will just fail. it's giving "I'm just looking, I won't touch anything" and then everything breaks π--argname value β accepted bynix-env,nix-instantiate,nix-shellandnix-build. when evaluating Nix expressions, the evaluator will automatically try to call functions it encounters. it can automatically call functions where every argument has a default value (e.g.{ argName ? defaultValue }: ...).
with --arg, you can also call functions that have arguments without a default value β or override a default value. so basically, if the evaluator encounters a function with an argument named name, it'll call it with value π₯
for instance, the top-level default.nix in Nixpkgs is actually a function:
{ # The system (e.g., `i686-linux') for which to build the packages.
system ? builtins.currentSystem
...
}: ...
so if you call this Nix expression (like when you do nix-env --install --attr pkgname), the function gets called automatically using the value builtins.currentSystem for the system argument. you can override that with --arg, e.g. nix-env --install --attr pkgname --arg system "i686-freebsd". (note that since the argument is a Nix string literal, you gotta escape the quotes, bestie β the shell is watching π)
--arg-from-filename path β passes the contents of the file at path as the argument name to Nix functions. file girlies rise π--arg-from-stdinname β passes the contents of stdin as the argument name to Nix functions. pipe it in, we love a stream π--argstrname value β like--arg, except the value isn't a Nix expression, it's a string. so instead of--arg system "i686-linux"(the outer quotes are there to keep the shell happy) you can just say--argstr system i686-linux. so much easier, no cap β¨--attr/-AattrPath β selects an attribute from the top-level Nix expression being evaluated. (nix-env,nix-instantiate,nix-buildandnix-shellonly, bestie.)
the attribute path attrPath is a sequence of attribute names separated by dots. so like, given a top-level Nix expression e, the attribute path xorg.xorgserver would cause the expression e.xorg.xorgserver to be used. see nix-env --install for some concrete examples π
and guess what β in addition to attribute names, you can also specify array indices! for instance, the attribute path foo.3.bar selects the bar attribute of the fourth element of the array in the foo attribute of the top-level expression. yes, 3 means the fourth one. programming is a nightmare but she's our nightmare π«Ά
--eval-storestore-url β the URL of the Nix store to use for evaluation, i.e. where to store derivations (.drvfiles) and the inputs referenced by them. keep your eval stuff separate, it's called boundaries πΈ--expr/-Eβ interprets the command line arguments as a list of Nix expressions to be parsed and evaluated, instead of as a list of file names of Nix expressions. (nix-instantiate,nix-buildandnix-shellonly.)
for nix-shell, this option is commonly used to give you a shell in which you can build the packages returned by the expression. but if you want a shell that already contains the built packages, ready to use β pass your expression to the nix-shell --packages convenience flag instead. pick your fighter π
-I/--includepath β adds an entry to the list of search paths used to resolve lookup paths. can be given multiple times, stack them up π§
paths added through -I take precedence over the nix-path configuration setting and the NIX_PATH environment variable. they go to the front of the line, periodt π
--impureβ allows access to mutable paths and repositories. living dangerously, we support it π--optionname value β sets the Nix configuration option name to value. this overrides settings in the Nix configuration file (seenix.conf5). override queen π--repairβ fixes corrupted or missing store paths by redownloading or rebuilding them. however β and listen closely β this is slow, because it requires computing a cryptographic hash of the contents of every path in the closure of the build. also note the warning undernix-store --repair-path. dramatic but true π
π Note β see man nix.conf for overriding configuration settings with command line flags. iykyk β¨
π COMMON ENVIRONMENT VARIABLES π
okay bestie, listen β basically most Nix commands read these environment variables when they run. That's the whole vibe. Here's the full list, no skips, no π§’.
β¨ Configuration environment variables β¨
These ones lowkey control how Nix loads its configuration. The configuration file documentation has the full deets, but here's the lineup:
NIX_CONF_DIRβ overrides the system configuration directory. πNIX_USER_CONF_FILESβ overrides the user configuration file locations.NIX_CONFIGβ gives Nix configuration settings inline. iconic.
πΈ Store setting environment variables πΈ
NIX_IGNORE_SYMLINK_STOREβ so normally? The Nix store directory (typically/nix/store) is not allowed to contain any symlink components, and that's on purpose: it's to prevent "impure" builds. Here's why β builders sometimes "canonicalise" paths by resolving all symlink components. Which means builds on different machines (where/nix/storeresolves to different locations) could totally yield different results. Usually that's not a problem, except when builds get deployed to machines where/nix/storeresolves differently. If you're sure you're not gonna do that, you can setNIX_IGNORE_SYMLINK_STOREto1.
Btw, if you're symlinking the Nix store so you can put it on a filesystem other than the root filesystem, on Linux you're better off using bind mount points, like:
$ mkdir /nix
$ mount -o bind /mnt/otherdisk/nix /nix
Go consult the mount 8 manual page for the details. π«Ά
NIX_STORE_DIRβ overrides the location of the Nix store. On Unix the default is/nix/store, set at compile time by thelibstore:store-dirbuild option. On Windows there's no compile-time setting at all; the default is%PROGRAMDATA%\nix\store, figured out at runtime using the%PROGRAMDATA%Known Folder. Also, see the Store Types chapter β every store has a store setting that links back to this as its default.NIX_LOG_DIRβ overrides where the Nix log directory lives. On Unix the default is/nix/var/log/nix, set at compile time by thelog-dirbuild option. On Windows there's no compile-time setting; the default is%PROGRAMDATA%\nix\log, determined at runtime using the%PROGRAMDATA%Known Folder. The Local Store, Local Daemon Store, and Experimental SSH Store with filesystem mounted all have per-store settings that override this.NIX_STATE_DIRβ overrides the location of the Nix state directory. On Unix the default is${localstatedir}/nix, wherelocalstatediris a compile-time build option that defaults to/nix/var. On Windows there's no compile-time setting; the default is%PROGRAMDATA%\nix\state, determined at runtime using the%PROGRAMDATA%Known Folder. And same as above β the Local Store, Local Daemon Store, and Experimental SSH Store with filesystem mounted have per-store settings that override this.NIX_DAEMON_SOCKET_PATHβ overrides the path to the Unix domain socket used to talk to the Nix daemon. It defaults todaemon-socket/socketinside the state directory (that'sNIX_STATE_DIRfor you π). Check the Local Daemon Store documentation for the whole story on how the socket path gets resolved.TMPDIRβ use this directory to store temporary files. Specifically that includes temporary build directories, and those can eat up a substantial amount of disk space. The default is/tmp. πNIX_REMOTEβ overrides the store setting.
π§ Nix language evaluator settings π§
NIX_SHOW_STATSβ if you set it to1, Nix prints some evaluation statistics, like the number of values allocated. cute little numbers β¨NIX_COUNT_CALLSβ if you set it to1, Nix prints how often functions were called during Nix expression evaluation. Super useful for profiling your Nix expressions. πGC_INITIAL_HEAP_SIZEβ if Nix was configured to use the Boehm garbage collector, this variable sets the initial size of the heap, in bytes. Defaults to384 MiB. Setting it low reduces memory consumption, but it'll increase runtime because of the overhead of garbage collection. pick your fighter πNIX_PATHβ a colon-separated list of search path entries used to resolve lookup paths. This environment variable overrides the value of thenix-pathconfiguration setting. You can also extend it using the-Ioption.
Example $ export NIX_PATH=/home/eelco/Dev:nixos-config=/etc/nixos
And here's the dramatic part: if NIX_PATH is set to an empty string, resolving search paths will always fail. periodt.
Example $ NIX_PATH= nix-instantiate --eval '<nixpkgs>' error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)
π User Directories π
Nix supports per-user configuration, state, and cache directories. These environment variables override where those directories live:
- user configuration directory (
[user configuration directory]{#user-conf-dir}):[NIX_CONFIG_HOME]{#env-NIXCONFIGHOME} - user state directory:
[NIX_STATE_HOME]{#env-NIXSTATEHOME} - user cache directory:
[NIX_CACHE_HOME]{#env-NIXCACHEHOME}
When none of those are set, the defaults depend on your platform:
- On Unix, the XDG base directories:
$XDG_CONFIG_HOME/nix,$XDG_STATE_HOME/nix,$XDG_CACHE_HOME/nix - On Windows, the Windows Known Folders:
%APPDATA%\nix\config,%LOCALAPPDATA%\nix\state,%LOCALAPPDATA%\nix\cache
For backwards compatibility, legacy Nix commands (like nix-env, nix-channel) use dotfiles in $HOME instead of these directories, unless use-xdg-base-directories is enabled. The new Nix commands (experimental) use the proper directories by default. slay for them honestly π¦
When use-xdg-base-directories is enabled, the configuration directory gets resolved like this:
$NIX_CONFIG_HOME, if it's defined- Otherwise, the platform default (e.g.
$XDG_CONFIG_HOME/nixon Unix)
And likewise for the state and cache directories. same energy, different folders.
π« Miscellaneous environment variables π«
IN_NIX_SHELLβ an indicator that tells you whether the current environment was set up bynix-shell. It can have the valuespureorimpure.
π Appendix: OS-specific conventions π
Quick heads up: this info isn't Nix-specific, it's just referenced up above. π«Ά
π Unix: XDG Base Directories π
The XDG Base Directory Specification defines standard locations for user-specific configuration, state, and cache files on Unix systems. The environment variables in play are:
[XDG_CONFIG_HOME]{#env-XDGCONFIGHOME}(default~/.config)[XDG_STATE_HOME]{#env-XDGSTATEHOME}(default~/.local/state)[XDG_CACHE_HOME]{#env-XDGCACHEHOME}(default~/.cache)[XDG_CONFIG_DIRS]{#env-XDGCONFIGDIRS}(default/etc/xdg) β a colon-separated list of additional configuration base directories, searched afterXDG_CONFIG_HOME
π Windows: Known Folders π
On Windows, Known Folders provide standard locations for application data. The relevant ones are:
[%APPDATA%]{#env-APPDATA}β per-user roaming application data[%LOCALAPPDATA%]{#env-LOCALAPPDATA}β per-user local application data[%PROGRAMDATA%]{#env-PROGRAMDATA}β system-wide application data
π₯ Example π₯
watch it go:
$ nix-store --optimise
hashing files in `/nix/store/qhqx7l2f1kmwihc9bnxs7rc159hsxnf3-gcc-4.1.1'
...
541838819 bytes (516.74 MiB) freed by hard-linking 54143 files;
there are 114486 files with equal contents out of 215894 files in total
look at that byte count. it's giving main character energy fr fr π
and that's a wrap, bestie!! π that little footer line at the very bottom of the real page holds the source, the version and the date for this manual β it's the nix-store --optimise(1) one, and it's the official receipts. go forth and optimise, you absolute icon ππ
π¦ where this page comes from
- fedora 44: nix-legacy 2.35.3-2.fc44 Β· LGPL-2.1-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms