How are flake dependencies fetched?

*when locking.

Once the flake is locked, other users and CI only need to fetch a flake input when it is referenced by an expression that is actually evaluated. In this case Nix does something like mapAttrs builtins.fetchTree on the lock file nodes, and since it’s a lazy language, and it doesn’t (afaik) make the mistake of forcing those attribute values ahead of time, this works out nicely.

For instance, if I use an input only for devShells but not for packages, users of that locked flake’s packages attribute won’t have to fetch that input.

The degree to which inputs are actually optional depends on the nature of the flake, and occasionally how it’s written.

Lazy paths by roberth · Pull Request #11367 · NixOS/nix · GitHub is a promising approach that delivers part of what lazy-trees brings to the table, but this is mostly about removing the copying to the store part, and not so much about the actual fetching.

The plan of Reuse input lock files · Issue #7730 · NixOS/nix · GitHub is to actually make locking lazy for transitive inputs, so that might have a more noticeable effect. (Unless you have slow-ish I/O to the store)

The Nix team has had to make time for other things, so progress on these issues hasn’t been as steady as I’d hoped. Help is of course appreciated if you want to contribute to these developments.

4 Likes