Nix flake losing its cache?

I’ve been using a nix flake with direnv in NixOS for a long time, but suddenly I’m facing an issue of the flake seemingly not caching. Every day I enter the directory (invoking the flake), it downloads the whole 1.4 GB for 10 minutes.

If I re-enter the directory immediately after downloading, it loads instantly. It seems to cache for a day at most before doing the whole download again. It shouldn’t ever lose the cache though, since it is a flake and its dependencies are fixed. Why is this happening and how can I fix it?

What exactly is it downloading? It’s hard to help debug without getting a better idea of how things are defined. Can you share the flake? Or the metadata?

Sure here’s the flake file in its entirety

{
  description = "Rust environment";

  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-20.09";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.mozilla = { url = "github:mozilla/nixpkgs-mozilla"; flake = false; };

  outputs =
    { self
    , nixpkgs
    , mozilla
    , flake-utils
    , ...
    } @inputs:
    let rustOverlay = final: prev:
          let rustChannel = prev.rustChannelOf {
            channel = "1.58.0";
            sha256 = "sha256-eQBpSmy9+oHfVyPs0Ea+GVZ0fvIatj6QVhNhYKOJ6Jk=";
            #channel = "nightly";
            #sha256 = "sha256-jCWXLjwbzTOjQ8H4sKLxkgBsUJpf6GXNnNg6VrKTpig=";
          };
          in
          { inherit rustChannel;
            rustc = rustChannel.rust;
            cargo = rustChannel.rust;
          };
    in flake-utils.lib.eachDefaultSystem
      (system:
        let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [
            (import "${mozilla}/rust-overlay.nix")
            rustOverlay
          ];
        };
        in {
          devShell = pkgs.mkShell {
            #RUST_BACKTRACE=1;
            #RUST_LOG="warn,novasymph=debug";
            buildInputs = with pkgs; [
              clang
              openssl
              (rustChannel.rust.override { extensions = [ "rust-src" ]; })
            ];
          };
        });
}

It’s also worth noting that a complete re-download happens every day I run a specific application nix run nixpkgs#logseq even though I’m not updating my system or the active nix channel between runs.

you could disable your automated garbage collection

or you can try GitHub - nix-community/nix-direnv: A fast, persistent use_nix/use_flake implementation for direnv [maintainer=@Mic92] which will add your shells to gc-roots so they’re not cleaned up or look at Flakes - NixOS Wiki

your nix run stuff is certainly being garbage collected, could you just install logseq so it’s already on your machine when you nix run nixpkgs#logseq?

Let’s split the problems apart. The nix run nixpkgs#run should has nothing to do with the flake pasted above. The semantics of that depend on how “flake:nixpgks” resolves on your machine. Normally it will resolve using the registry, but some people change it locally. By default it is nixpkgs-unstable, which does change often, thus you will download the 27MB fairly often. You can change this with something like nix registry add nixpkgs github:NixOS/nixpkgs/3sdfkl34tSOMEHASH23rlkjdf0sdf if you want to pin it down and not have it change. (or you adjust your tarball-ttl settings, but let’s avoid that for the moment). The downside/upside is that now you are in charge of when/how the underlying nixpkgs changes.

Next, the posted flake. The mentioned 1.4GB seems to be caused by GC. It’s not the flakes, but the underlying packages that are either changing, or being removed daily. Adding roots via the direnv method mentioned or even manually can prevent this. Or disable your automatic GC. A quick method there could be nix develop --profile ./make-me-a-gc-root-symlink which will automatically register it as a gc root in whatever location you wish. Again, with that power comes the responsibility to understand that now it will never be GC’d until you remove that symlink (potential issue: you forget about it and 1 year from now you wonder why the packages are not cleaned up for you). This is pretty close to what the nix-direnv/use-flake thing does under the hood. It places it into a hidden location (i think .direnv).

To add to what tomberek said about pinning the nixpkgs flake. You can also do it declaratively, via the nixos config option nix.registry.nixpkgs to have the pins update with and/or match your system. In particular can set nix.registry.nixpkgs.flake = inputs.nixpkgs. You can also name it whatever you would like and pin multiple inputs (not just nixpkgs)