Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remote instantiation (NIX_REMOTE, --store) is an order of magnitude slower than local instantiation + nix copy #10119

Open
Atemu opened this issue Mar 1, 2024 · 5 comments

Comments

@Atemu
Copy link
Member

Atemu commented Mar 1, 2024

Describe the bug

A clear and concise description of what the bug is.

When doing remote builds, instantiation time is unreasonably long (many seconds for a simple package). About an order of magnitude slower in fact:

$ nix run nixpkgs#hyperfine -- -w 1 -- 'nix copy $(nix-instantiate -A hello --system x86_64-linux) --to ssh-ng://remote'
Benchmark 1: nix copy $(nix-instantiate -A hello --system x86_64-linux) --to ssh-ng://remote
  Time (mean ± σ):     810.2 ms ±  34.2 ms    [User: 103.5 ms, System: 26.9 ms]
  Range (min … max):   768.9 ms … 873.3 ms    10 runs
 

$ nix run nixpkgs#hyperfine -- -w 1 -- "nix-instantiate -A hello --system x86_64-linux --store ssh-ng://remote"
Benchmark 1: nix-instantiate -A hello --system x86_64-linux --store ssh-ng://remote
  Time (mean ± σ):      8.616 s ±  0.263 s    [User: 0.632 s, System: 0.328 s]
  Range (min … max):    8.070 s …  8.949 s    10 runs
 

Steps To Reproduce

  1. nix copy $(nix-instantiate -A hello --system x86_64-linux) --to ssh-ng://remote
  2. nix-instantiate -A hello --store ssh-ng://remote
  3. Observe difference

Expected behavior

A clear and concise description of what you expected to happen.

Remote instantiation should be the same speed or faster than local instantiation + copy.

Rationale for faster than local + copy: .drv files should not need to be written locally during a remote build (certainly not in the hot path), saving many IOPS.

nix-env --version output

nix-env (Nix) 2.18.1
$ uname -a
Darwin hostname 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000 arm64 arm Darwin

Additional context

During remote instantiation, there appears to be a constant 1Mbit/s upload stream, no matter whether I previously instantiated the exact same drv or not.

Priorities

Add 👍 to issues you find important.

@Atemu Atemu added the bug label Mar 1, 2024
@thufschmitt
Copy link
Member

@Atemu does that also happen with --store ssh-ng://remote --eval-store auto?

@Atemu
Copy link
Member Author

Atemu commented Mar 2, 2024

Indeed it does not!

$ nix run nixpkgs#hyperfine -- -w 1 -- "nix-instantiate -A hello --system x86_64-linux --store ssh-ng://remote --eval-store auto"
Benchmark 1: nix-instantiate -A hello --system x86_64-linux --store ssh-ng://remote --eval-store auto
  Time (mean ± σ):     261.7 ms ±   9.7 ms    [User: 134.4 ms, System: 46.2 ms]
  Range (minmax):   251.1 ms284.9 ms    11 runs
 

Thanks :)

What is this wizardry and why don't I cast it by default?

Can I make that the default somehow? I don't want to have to specify it on every invocation that does a remote build.

@thufschmitt
Copy link
Member

What is this wizardry and why don't I cast it by default?

--store sets the store used by Nix, both for building and for evaluation. This means that just setting it will make every store-operation during the evaluation use the remote store (this includes writing the .drv file for every call to builtins.derivation, uploading every interpolated path, etc..). And because the evaluator is strongly sequential, this can be really slow.

Using --eval-store auto makes nix use the local store for the evaluation (auto means “daemon or direct write to a local store”), and copy the resulting drv tree to the remote store – so very similar to nix-instantiate && nix copy.
Your last benchmark is probably a bit biased btw because I suspect that nix-instantiate --eval-store foo --store bar won't copy the closure to bar as it doesn't require building it.

Can I make that the default somehow? I don't want to have to specify it on every invocation that does a remote build.

Apparently not, because eval-store is just a cli flag, not an option – but I think that could be reasonably easy to fix.

More broadly, this store thing is a bit of a footgun, it would be nice to find a good interface so that people don't run into issues like the current one. Any suggestion to improve it is welcome :)

@Atemu
Copy link
Member Author

Atemu commented Mar 4, 2024

Related: #6893

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2024-03-04-nix-team-meeting-minute-130/40830/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants