Nix 2.32.0 released

Hi,

I’m pleased to announce the availability of Nix 2.32.0. It is available from releases.nixos.org.

Release notes

Incompatible changes

  • Removed support for daemons and clients older than Nix 2.0 #13951

    We have dropped support in the daemon worker protocol for daemons and clients that don’t speak at least version 18 of the protocol. This first Nix release that supports this version is Nix 2.0, released in February 2018.

  • Derivation JSON format now uses store path basenames only #13570 #13980

    Experience with many JSON frameworks (e.g. nlohmann/json in C++, Serde in Rust, and Aeson in Haskell) has shown that the use of the store directory in JSON formats is an impediment to systematic JSON formats, because it requires the serializer/deserializer to take an extra paramater (the store directory).

    We ultimately want to rectify this issue with all JSON formats to the extent allowed by our stability promises. To start with, we are changing the JSON format for derivations because the nix derivation commands are — in addition to being formally unstable — less widely used than other unstable commands.

    See the documentation on the JSON format for derivations for further details.

  • C API: nix_get_attr_name_byidx, nix_get_attr_byidx take a nix_value * instead of const nix_value * #13987

    In order to accommodate a more optimized internal representation of attribute set merges these functions require
    a mutable nix_value * that might be modified on access. This does not break the ABI of these functions.

New features

  • C API: Add lazy attribute and list item accessors #14030

    The C API now includes lazy accessor functions for retrieving values from lists and attribute sets without forcing evaluation:

    • nix_get_list_byidx_lazy() - Get a list element without forcing its evaluation
    • nix_get_attr_byname_lazy() - Get an attribute value by name without forcing evaluation
    • nix_get_attr_byidx_lazy() - Get an attribute by index without forcing evaluation

    These functions are useful when forwarding unevaluated sub-values to other lists, attribute sets, or function calls. They allow more efficient handling of Nix values by deferring evaluation until actually needed.

    Additionally, bounds checking has been improved for all _byidx functions to properly validate indices before access, preventing potential out-of-bounds errors.

    The documentation for NIX_ERR_KEY error handling has also been clarified to specify when this error code is returned.

  • HTTP binary caches now support transparent compression for metadata

    HTTP binary cache stores can now compress .narinfo, .ls, and build log files before uploading them,
    reducing bandwidth usage and storage requirements. The compression is applied transparently using the
    Content-Encoding header, allowing compatible clients to automatically decompress the files.

    Three new configuration options control this behavior:

    • narinfo-compression: Compression method for .narinfo files
    • ls-compression: Compression method for .ls files
    • log-compression: Compression method for build logs in log/ directory

    Example usage:

    nix copy --to 'http://cache.example.com?narinfo-compression=gzip&ls-compression=gzip' /nix/store/...
    nix store copy-log --to 'http://cache.example.com?log-compression=br' /nix/store/...
    
  • Temporary build directories no longer include derivation names #13839

    Temporary build directories created during derivation builds no longer include the derivation name in their path to avoid build failures when the derivation name is too long. This change ensures predictable prefix lengths for build directories under /nix/var/nix/builds.

  • External derivation builders #14145

    These are helper programs that Nix calls to perform derivations for specified system types, e.g. by using QEMU to emulate a different type of platform. For more information, see the external-builders setting.

    This is currently an experimental feature.

Performance improvements

  • Optimize memory usage of attribute set merges #13987

    Attribute set update operations have been optimized to
    reduce reallocations in cases when the second operand is small.

    For typical evaluations of nixpkgs this optimization leads to ~20% less memory allocated in total
    without significantly affecting evaluation performance.

    See eval-attrset-update-layer-rhs-threshold

  • Substituted flake inputs are no longer re-copied to the store #14041

    Since 2.25, Nix would fail to store a cache entry for substituted flake inputs, which in turn would cause them to be re-copied to the store on initial evaluation. Caching these inputs results in a near doubling of performance in some cases — especially on I/O-bound machines and when using commands that fetch many inputs, like nix flake [archive|prefetch-inputs].

  • nix flake check now skips derivations that can be substituted #13574

    Previously, nix flake check would evaluate and build/substitute all
    derivations. Now, it will skip downloading derivations that can be substituted.
    This can drastically decrease the time invocations take in environments where
    checks may already be cached (like in CI).

  • fetchTarball and fetchurl now correctly substitute (#14138)

    At some point we stopped substituting calls to fetchTarball and fetchurl with a set narHash to avoid incorrectly substituting things in fetchTree, even though it would be safe to substitute when calling the legacy fetch{Tarball,url}. This fixes that regression where it is safe.

  • Started moving AST allocations into a bump allocator #14088

    This leaves smaller, immutable structures in the AST. So far this saves about 2% memory on a NixOS config evaluation.

Contributors

This release was made possible by the following 32 contributors:

56 Likes

Looks like a lot of great fixes and performance boosts. Great job!

5 Likes

PR for Nixpkgs use which updates nixVersions.latest to 2.32.0 is up.

10 Likes

Dang, that was fast. I was gonna test on my Ampere. Glad to see it already in nixpkgs.

4 Likes

This is indeed great! IMO, that’s a great move. I would even suggest that the new release announcement post should be written only once it is merged in nixpkgs.

1 Like

I disagree, making a release of nix on github is completely independent of merging it into nixpkgs

5 Likes

That’s my goal!

My goal: a release PR opened within a few hours of the tag occurring upstream.

4 Likes

Nix 2.32.1 was released; it contains these updates.

It’s available in Nixpkgs also since nixVersions.nix_2_32: 2.32.0 -> 2.32.1 by zowoq · Pull Request #452753 · NixOS/nixpkgs · GitHub.

8 Likes

A thing that we have overlooked in the release notes is a rather big flake error messages improvement. Now error messages include the original location of files and not their copies in the nix store. As a result, error messages about missing files are now much more legible. When trying to import a non-existent file in a flake:

{
  outputs =
    { ... }:
    {
      a = import ./foo;
    };
}

instead of error messages like:

error:
       … while calling the 'import' builtin
         at /nix/store/jddhnbpcfn3l6vb4i6z21n7xmcig1m09-source/flake.nix:5:11:
            4|     {
            5|       a = import ./foo;
             |           ^
            6|     };

       error: path '/nix/store/jddhnbpcfn3l6vb4i6z21n7xmcig1m09-source/foo' does not exist

You now get:

error:
       … while calling the 'import' builtin
         at /tmp/tmp.scdeeC8Gm1/flake.nix:5:11:
            4|     {
            5|       a = import ./foo;
             |           ^
            6|     };

       error: Path 'foo' does not exist in Git repository "/tmp/tmp.scdeeC8Gm1".

This supersedes #12915 and has been implemented as a side-effect of another bugfix in #14050. This does surface a pre-existing issue with impure evaluation and builtins.readDir builtins.storeDir (Fix fetchToStore caching by edolstra · Pull Request #14050 · NixOS/nix · GitHub), but that is expected to be resolved soonish.

10 Likes