diff --git a/doc/manual/rl-next/cached-substituted-inputs.md b/doc/manual/rl-next/cached-substituted-inputs.md new file mode 100644 index 000000000..b0b53a213 --- /dev/null +++ b/doc/manual/rl-next/cached-substituted-inputs.md @@ -0,0 +1,10 @@ +--- +synopsis: "Substituted flake inputs are no longer re-copied to the store" +prs: [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 a performance in +some cases — especially on I/O-bound machines and when using commands that +fetch many inputs, like `nix flake archive/prefetch-inputs` diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index d40e97aa9..045aafdcb 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -4,6 +4,7 @@ #include "nix/fetchers/fetch-to-store.hh" #include "nix/util/json-utils.hh" #include "nix/fetchers/fetch-settings.hh" +#include "nix/fetchers/fetch-to-store.hh" #include @@ -336,6 +337,15 @@ std::pair, Input> Input::getAccessorUnchecked(ref sto accessor->fingerprint = getFingerprint(store); + // Store a cache entry for the substituted tree so later fetches + // can reuse the existing nar instead of copying the unpacked + // input back into the store on every evaluation. + if (accessor->fingerprint) { + ContentAddressMethod method = ContentAddressMethod::Raw::NixArchive; + auto cacheKey = makeFetchToStoreCacheKey(getName(), *accessor->fingerprint, method, "/"); + settings->getCache()->upsert(cacheKey, *store, {}, storePath); + } + accessor->setPathDisplay("«" + to_string() + "»"); return {accessor, *this};