{
description = "Example of a large flake input being problematic";
inputs = {
qwen = {
url = "https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF/resolve/main/Qwen3.6-35B-A3B-UD-Q2_K_XL.gguf?download=true";
flake = false;
};
};
outputs = { ... }: { };
}
When I run nix flake update in that directory, it downloads the flake input.
But once the download completes it stops at the 100% mark and my system’s memory usage starts going up. It will continue to rise until either I kill -9 the Nix process (ctrl+c does not work) or my system runs out of memory and locks up.
I wanted to put these models into the Nix store for easier clean up and better caching. Is that an irresponsible way to use flake inputs?
Yes. flake = false; is a code smell.
Use npins or nix-prefetch-url or so on if you want it in the nix store.
If you don’t need it in the store, you can just use curl.
This one’s about 12Gb. They can get several times bigger. The reasons I’d like to have it in the nix store is so that I can share it between users and share it with other hosts without having to pull it from upstream again.
I think npins is the way to go but I’ll need some time to try. I like that it shouldn’t try to update this “input” every time I run nix flake update.
Does this have to be managed using npins/flake inputs? It seems like a static artifact that you won’t be changing often - you could just get away with using the standard nix fetch* functions and writing a derivation for this. That’s the usual way to deal with things like this.
I tried the flake extract provided and nix briefly consumed 30GB of RAM before dropping down to 22 GB of RAM. I’m not sure if there’s an issue here with having two copies of the input.
Yep, pretty much. except instead of main have a commit hash so if it changes in a new commit it will keep using the same version. You don’t even need a qwen3.6.nix, you can just put that in flake.nix or really anywhere else.
Took awhile for me to get time to try it but it worked.
I should note that it’s critical to use pkgs.fetchurl because builtins.fetchurl suffers the same memory usage problem as a large flake input.
I… wonder if that should be reported as a bug (or if it already has been)
That’s “intended” and not a bug; the builtin fetchers aren’t builders and don’t create derivations, while the pkgs.fetch* alternatives do.
This has a bunch of implications on when to use which, notably builtins.fetch* doesn’t cause IFD, but as you sawpkgs.fetch* has other advantages.
As a rule of thumb, use pkgs.fetch* whenever you’re building software from a source, or something similar, and builtins.fetch* if you’re trying to depend on someone else’s nix code (but ideally, use npins or flakes instead in that scenario).
flake inputs use the same code as builtins.fetch* behind the scenes, by the way, so yes, they behave the same way. npins actually literally use the same function calls.
If there is a bug here, it’s lack of documentation of this distinction. But that’s because neither the nix nor nixpkgs manuals are really the right place for it, and we simply don’t have good, fully integrated docs.