Combine the power of nix-eval-jobs
with nix-output-monitor
to speed-up your
evaluation and building process. nix-fast-build
an also integrates with remote
machines by uploading the current flake, performing the evaluation/build
remotely, and then transferring the resultant store paths back to you.
Problem: Evaluating and building big flakes i.e. with numerous NixOS
machines can be painfully slow. For instance, rebuilding the already-compiled
disko integration test suite demands
1:50 minutes on an AMD Ryzen 9 7950X3D. But, it only takes a
10 seconds with
nix-fast-build
.
Solution: nix-fast-build
makes builds faster by evaluating and building
your nix packages concurrently, reducing the overall time.
Under the hood:
- It leverages the output from
nix-eval-jobs
to evaluate flake attributes in parallel. - As soon as attributes complete evaluation,
nix-fast-build
initiates their build, even if the overall evaluation is ongoing. - Lastly,
nix-output-monitor
to show the build progress nicely. - (Optional) Once a build finishes,
nix-fast-build
can initiate its upload to a designated remote binary cache.
To get started, run:
$ nix-fast-build
or:
$ nix run github:Mic92/nix-fast-build
This command will concurrently evaluate all systems in .#checks
and build the
attributes in .#checks.$currentSystem
.
Enjoy faster and more efficient NixOS builds with nix-fast-build
!
When leveraging the remote-builder protocol, uploading pre-built paths or
sources from the local machine can often turn into a bottleneck.
nix-fast-build
does not use the remote-builder protocol. Instead it uploads
only the flake and executes all evaluation/build operations on the remote end.
At the end nix-fast-build
will download the finished builds to the local
machine while not having to download all build dependencies in between.
Here is how to use it:
nix run github:Mic92/nix-fast-build -- --remote youruser@yoursshhostname
Replace youruser@yoursshhostname
with your SSH login credentials for the
target machine. Please note that as of now, you must be recognized as a trusted
user on the remote endpoint to access this feature.
By default, Nix-output-monitor
(abbreviated as nom
) updates its output every
0.5 seconds. In standard terminal environments, this frequent update is
unnoticeable, as nom
erases the previous output before displaying the new one.
However, in Continuous Integration (CI) systems, each update appears as a
separate line of output.
To make output more concise for CI environments, use the --no-nom
flag. This
replaces nom
with a streamlined status reporter, which updates only when
there's a change in the number of pending builds, uploads, or downloads.
By default, nix build
will download pre-built packages, leading to needless
downloads even when there are no changes to any package. This can be especially
burdensome for CI environments without a persistent Nix store, such as GitHub
Actions.
To optimize this, use the --skip-cached
flag with nix-fast-build
. This
ensures that only those packages missing from the binary caches will be built.
By default, nix-fast-build
evaluates all architectures but only initiates
builds for the current system. You can modify this behavior with the --systems
flag. For instance, using --systems "aarch64-linux x86_64-linux"
will prompt
builds for both aarch64-linux
and x86_64-linux
architectures. Ensure that
your system is capable of building for the specified architectures, either
locally or through the remote builder protocol.
nix-fast-build
by default builds .#checks.$currentSystem
, which refers to
all checks for the current flake. You can modify this default behavior by using
the --flake
flag to specify a different attribute path.
Example:
$ nix run github:Mic92/nix-fast-build -- --flake github:NixOS/nixpkgs#legacyPackages.x86_64-linux.hello
Note: Always provide the complete flake path. Unlike nix build
,
nix-fast-build
does not iterate over different attributes; the full path must
be explicitly stated.
By default nix-fast-build will evaluate all systems in .#checks
, you can limit
it to the current system by using this command:
$ nix run github:Mic92/nix-fast-build -- --skip-cached --no-nom --flake ".#checks.$(nix eval --raw --impure --expr builtins.currentSystem)"
usage: nix-fast-build [-h] [-f FLAKE] [-j MAX_JOBS] [--option name value] [--remote-ssh-option name value] [--no-nom]
[--systems SYSTEMS] [--retries RETRIES] [--no-link] [--out-link OUT_LINK] [--remote REMOTE]
[--always-upload-source] [--no-download] [--skip-cached] [--copy-to COPY_TO] [--debug]
[--eval-max-memory-size EVAL_MAX_MEMORY_SIZE] [--eval-workers EVAL_WORKERS]
options:
-h, --help show this help message and exit
-f FLAKE, --flake FLAKE
Flake url to evaluate/build (default: .#checks
-j MAX_JOBS, --max-jobs MAX_JOBS
Maximum number of build jobs to run in parallel (0 for unlimited)
--option name value Nix option to set
--remote-ssh-option name value
ssh option when accessing remote
--no-nom Don't use nix-output-monitor to print build output (default: false)
--systems SYSTEMS Space-separated list of systems to build for (default: current system)
--retries RETRIES Number of times to retry failed builds
--no-link Do not create an out-link for builds (default: false)
--out-link OUT_LINK Name of the out-link for builds (default: result)
--remote REMOTE Remote machine to build on
--always-upload-source
Always upload sources to remote machine. This is needed if the remote machine cannot access all sources
(default: false)
--no-download Do not download build results from remote machine
--skip-cached Skip builds that are already present in the binary cache (default: false)
--copy-to COPY_TO Copy build results to the given path (passed to nix copy, i.e. file:///tmp/cache?compression=none)
--debug debug logging output
--eval-max-memory-size EVAL_MAX_MEMORY_SIZE
Maximum memory size for nix-eval-jobs (in MiB) per worker. After the limit is reached, the worker is restarted.
--eval-workers EVAL_WORKERS
Number of evaluation threads spawned