Nix: Reasonable Default Configs

Updated November 30, 2022

I’ve now been using Nix, the package manager, fulltime on my personal machines for over a year. I run NixOS on my personal desktop/laptop and VMs, so I have some reasonable experience using it.

I really enjoy using Nix, and think it’s a very useful tool, but it definitely needs a lot of tweaking.

Today I want to share some of the config settings in Nix that most users probably want to change. The defaults that Nix uses for these settings don’t make that much sense to me, and most people who actually use Nix should probably consider changing them.

Just a note, Nix had a longstanding bug where it displayed the wrong default values in the manual, so make sure you are looking at the latest unstable Nix manual.

I’ll go into them in detail below, but here are the settings I want to talk about. I’ve grouped them into tiers; Almost always set, Set if understood, and Set for developers.

# Almost always set
connect-timeout = 5
log-lines = 25
min-free = 128000000
max-free = 1000000000

# Set if understood
experimental-features = nix-command flakes
fallback = true
warn-dirty = false
auto-optimise-store = true

# Set for developers
keep-outputs = true

Almost always set Link to heading

These are settings that I think are no-brainers to change for just about everyone, and they should probably just be the default values.

connect-timeout Link to heading

The timeout (in seconds) for establishing connections in the binary cache substituter. It corresponds to curl’s –connect-timeout option. A value of 0 means no limit.

  • Default: 0
  • Reasonable: 5

The default of 0 is equal to a timeout of 300 seconds. This seems pretty unreasonable for most users.

This is especially important if you have multiple caches setup, as any offline caches will just hang for this whole time. Assuming you’ve also set fallback = true, then setting connect-timeout to a reasonable value will let you have binary caches on your local machines that are only occasionally online.

log-lines Link to heading

The number of lines of the tail of the log to show if a build fails.

  • Default: 10
  • Reasonable: 25

These log lines are only shown on a failed build, and I’ve found that usually the last 10 lines aren’t useful for figuring out what actually failed. Setting it to something even a little bit larger is often enough to debug the build.

You can also set this to something very large to output the whole build log.

min-free/max-free Link to heading

When free disk space in /nix/store drops below min-free during a build, Nix performs a garbage-collection until max-free bytes are available or there is no more garbage. A value of 0 (the default) disables this feature.

  • min-free
    • Default: 0
    • Reasonable: 128000000 (128 MB)
  • max-free
    • Default: -1
    • Reasonable: 1000000000 (1 GB)

Note: These are actually most useful if you setup /nix on it’s own partition, as long as you give it enough space then you never need to manually garbage collect.

Nix has a tendency to use a lot of space, especially if you are developing with it. By default nothing will be deleted unless you manually collect garbage with nix-collect-garbage.

By setting min-free to a reasonable small value, you can ensure that it doesn’t fully fill the partition, which can cause problems if /nix/store is on the same partition as the rest of your system.

Users will probably want to tweak these settings themselves, but changing these settings from the defaults will at least ensure that they don’t run out of disk-space.

Set if understood Link to heading

These settings are things that most users should probably set, but you should definitely understand them first.

experimental-features = flakes Link to heading

  • Default: nix-command
  • Reasonable: nix-command flakes

This enables the technically experimental feature Flakes.

Most development with Nix recently is using flakes, and as a user you probably want to enable them. If you are a new user especially I’d suggest just using the flakes interface instead of the legacy one.

The current status is that there is an in-progress plan for a plan to stabilize flakes, though there are still lots of very legitimate concerns about them. I’m especially concerned about how they’ve handled the global registry, which you can’t disable easily even though there is a very minor PR to do so. If possible I’d suggest you disable the global registry as well, for all the reasons mentioned in those links.

Even with the drawbacks though, they are just clearly a better interface to use Nix with, and they’ve been in broad use for several years now.

fallback Link to heading

If set to true, Nix will fall back to building from source if a binary substitute fails. This is equivalent to the –fallback flag. The default is false.

  • Default: false
  • Reasonable: true

That description is sort of a lie. It’s somewhat common for users to have multiple substituters (caches) setup, either for sharing builds within a company/project or just for caching downloads in your local network. Nix makes it pretty easy to do this on your own machines, especially if they run NixOS, see the wiki.

This setting, if set to false, will cause the build to fail if any of the caches are unavailable. That seems pretty nonsensical, and seems like a common complaint, so I opened a PR to fix it.

Even after that fix goes in, I expect that the way most people expect Nix to work is with this set to true. It is literally setup to have reproducible builds, so failing when caches aren’t available doesn’t make sense in most cases.

Some people may want this set to false, especially on slower devices, but you probably want this set to true.

warn-dirty Link to heading

Whether to warn about dirty Git/Mercurial trees.

  • Default: true
  • Reasonable: false

I don’t disagree with the default here, but most people probably don’t need these warnings.

auto-optimise-store Link to heading

If set to true, Nix automatically detects files in the store that have identical contents, and replaces them with hard links to a single copy. This saves disk space. If set to false (the default), you can still run nix-store –optimise to get rid of duplicate files.

  • Default: false
  • Reasonable: true

This can save quite a lot of disk space, especially if you upgrade frequently and develop on the machine. I always recommend it, but it does make the layout of /nix/store a little confusing for some people.

Set for developers Link to heading

keep-outputs Link to heading

If true, the garbage collector will keep the outputs of non-garbage derivations. If false (default), outputs will be deleted unless they are GC roots themselves (or reachable from other roots). In general, outputs must be registered as roots separately. However, even if the output of a derivation is registered as a root, the collector will still delete store paths that are used only at build time (e.g., the C compiler, or source tarballs downloaded from the network). To prevent it from doing so, set this option to true.

  • Default: false
  • Reasonable: true

This ensures that packages needed for building other packages are kept in the store. If you’re going to be building packages locally, this is very useful to prevent having to redownload things a lot.

Keep in mind that this will cause your nix store to get pretty large.