-
-
Notifications
You must be signed in to change notification settings - Fork 13.9k
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
nixos-rebuild --switch
too slow, tracking issue
#57477
Comments
See also NixOS/rfcs#22. |
@infinisil I think you mean "decreases"? |
Another (general) approach to debugging evaluation times would be to add a flamegraph output to nix itself. Because apart from very simple counters we have no way to debug the evaluation as far as I’m aware of. The bazel build system has an option to debug their evaluator by outputting the flamegraph format that can be read by the Chromium devtools (and so probably also firebug). We should add the same. |
I just wrote a little script to minimize for i in $(seq $(( $(cat module-list.nix | wc -l) - 1 )) -1 2); do
echo $i
if nix-instantiate ../lib/eval-config.nix --arg system 'builtins.currentSystem' --arg modules '[ ./configuration.nix ]' --arg baseModules "$(cat module-list.nix | sed ${i}d)" -A config.system.build.toplevel; then
sed -i ${i}d module-list.nix
fi
done I put a minimal {
boot.loader.grub.device = "nodev";
fileSystems."/".device = "x";
} Then $ cd ~/src/nixpkgs/nixos/modules
$ ./minimize-modules
$ ./minimize-modules I needed two runs because of module dependencies from earlier to later modules in the list. The resulting [
./config/xdg/autostart.nix
./config/xdg/icons.nix
./config/xdg/menus.nix
./config/xdg/mime.nix
./config/i18n.nix
./config/krb5/default.nix
./config/ldap.nix
./config/networking.nix
./config/nsswitch.nix
./config/power-management.nix
./config/pulseaudio.nix
./config/shells-environment.nix
./config/swap.nix
./config/sysctl.nix
./config/system-environment.nix
./config/system-path.nix
./config/users-groups.nix
./hardware/all-firmware.nix
./hardware/ckb-next.nix
./i18n/input-method/default.nix
./i18n/input-method/ibus.nix
./misc/assertions.nix
./misc/documentation.nix
./misc/extra-arguments.nix
./misc/ids.nix
./misc/lib.nix
./misc/label.nix
./misc/meta.nix
./misc/nixpkgs.nix
./misc/version.nix
./programs/bash/bash.nix
./programs/shadow.nix
./programs/ssh.nix
./programs/zsh/oh-my-zsh.nix
./programs/zsh/zsh.nix
./programs/zsh/zsh-autosuggestions.nix
./programs/zsh/zsh-syntax-highlighting.nix
./rename.nix
./security/acme.nix
./security/chromium-suid-sandbox.nix
./security/google_oslogin.nix
./security/oath.nix
./security/pam.nix
./security/pam_usb.nix
./security/pam_mount.nix
./security/polkit.nix
./security/rtkit.nix
./security/wrappers/default.nix
./security/sudo.nix
./services/cluster/kubernetes/addons/dns.nix
./services/cluster/kubernetes/addon-manager.nix
./services/cluster/kubernetes/apiserver.nix
./services/cluster/kubernetes/controller-manager.nix
./services/cluster/kubernetes/default.nix
./services/cluster/kubernetes/flannel.nix
./services/cluster/kubernetes/kubelet.nix
./services/cluster/kubernetes/pki.nix
./services/cluster/kubernetes/proxy.nix
./services/cluster/kubernetes/scheduler.nix
./services/databases/mysql.nix
./services/desktops/accountsservice.nix
./services/desktops/bamf.nix
./services/desktops/dleyna-renderer.nix
./services/desktops/dleyna-server.nix
./services/desktops/pantheon/contractor.nix
./services/desktops/pantheon/files.nix
./services/desktops/flatpak.nix
./services/desktops/geoclue2.nix
./services/desktops/gsignond.nix
./services/desktops/gnome3/at-spi2-core.nix
./services/desktops/gnome3/evolution-data-server.nix
./services/desktops/gnome3/file-roller.nix
./services/desktops/gnome3/gnome-disks.nix
./services/desktops/gnome3/gnome-documents.nix
./services/desktops/gnome3/gnome-keyring.nix
./services/desktops/gnome3/gnome-online-accounts.nix
./services/desktops/gnome3/gnome-remote-desktop.nix
./services/desktops/gnome3/gnome-online-miners.nix
./services/desktops/gnome3/gnome-terminal-server.nix
./services/desktops/gnome3/gnome-user-share.nix
./services/desktops/gnome3/gvfs.nix
./services/desktops/gnome3/rygel.nix
./services/desktops/gnome3/seahorse.nix
./services/desktops/gnome3/sushi.nix
./services/desktops/gnome3/tracker.nix
./services/desktops/gnome3/tracker-miners.nix
./services/desktops/telepathy.nix
./services/desktops/tumbler.nix
./services/desktops/zeitgeist.nix
./services/hardware/bluetooth.nix
./services/hardware/bolt.nix
./services/hardware/udev.nix
./services/hardware/udisks2.nix
./services/hardware/upower.nix
./services/logging/rsyslogd.nix
./services/logging/syslog-ng.nix
./services/mail/postgrey.nix
./services/misc/etcd.nix
./services/misc/nix-daemon.nix
./services/misc/nixos-manual.nix
./services/misc/packagekit.nix
./services/misc/sssd.nix
./services/network-filesystems/samba.nix
./services/networking/avahi-daemon.nix
./services/networking/bind.nix
./services/networking/ddclient.nix
./services/networking/dhcpcd.nix
./services/networking/dhcpd.nix
./services/networking/dnsmasq.nix
./services/networking/firewall.nix
./services/networking/flannel.nix
./services/networking/iodine.nix
./services/networking/mstpd.nix
./services/networking/networkmanager.nix
./services/networking/racoon.nix
./services/networking/ssh/sshd.nix
./services/networking/unbound.nix
./services/networking/wpa_supplicant.nix
./services/printing/cupsd.nix
./services/security/certmgr.nix
./services/security/cfssl.nix
./services/security/fprintd.nix
./services/system/dbus.nix
./services/system/nscd.nix
./services/ttys/agetty.nix
./services/web-apps/matomo.nix
./services/web-servers/nginx/default.nix
./services/x11/colord.nix
./services/x11/hardware/libinput.nix
./services/x11/gdk-pixbuf.nix
./services/x11/xserver.nix
./system/activation/activation-script.nix
./system/activation/top-level.nix
./system/boot/grow-partition.nix
./system/boot/kernel.nix
./system/boot/loader/efi.nix
./system/boot/loader/grub/grub.nix
./system/boot/loader/loader.nix
./system/boot/modprobe.nix
./system/boot/resolved.nix
./system/boot/stage-1.nix
./system/boot/stage-2.nix
./system/boot/systemd.nix
./system/etc/etc.nix
./tasks/filesystems.nix
./tasks/kbd.nix
./tasks/network-interfaces.nix
./virtualisation/containers.nix
./virtualisation/docker.nix
./virtualisation/lxcfs.nix
./virtualisation/openvswitch.nix
./virtualisation/virtualbox-guest.nix
./virtualisation/virtualbox-host.nix
./virtualisation/vmware-guest.nix
] Evaluation time for this (trivial) $ time nix-instantiate ../lib/eval-config.nix --arg system 'builtins.currentSystem' --arg modules '[ ./configuration.nix ]' --arg baseModules 'import ./original-module-list.nix' -A config.system.build.toplevel
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
/nix/store/7zxpkl6ayw45bf3xf6l3cd5pxzb7zg6q-nixos-system-nixos-19.03.git.42bf842.drv
1.59s user 0.17s system 94% cpu 1.854 total
$ time nix-instantiate ../lib/eval-config.nix --arg system 'builtins.currentSystem' --arg modules '[ ./configuration.nix ]' --arg baseModules 'import ./module-list.nix' -A config.system.build.toplevel
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
/nix/store/2sylcv6g034jw4r36qywbnpxq7zkf0f3-nixos-system-nixos-19.03.git.42bf842.drv
0.69s user 0.10s system 90% cpu 0.868 total Todo: Repeat for real |
Does Guix also suffer from this? Has anyone done benchmarking on Guix vs Nix? I am still using Nix exclusively, but there are costs to a new language ecosystem (lack of tooling). Using an existing interpreter and language is from a maintenance perspective appealing. |
If Also, it may be that switching nixos-rebuild to Nix 2 can speedup in build-phase (where many small files are built). At least it doesn't block on stdout buffering. |
@danbst |
@infinisil oh ok. It just title says "nixos-rebuild --switch is slow", so I put my 2cents... Have you counted how many option declarations do you have in your configs (excluding base modules)? I see that minimal configuration takes 2.74s to evaluate, but your system takes 12s (excluding docs). Module system author says it is linear in number of modules+number of options+number of option declarations, which makes me wonder, what goes wrong. |
I do have a bunch of options defined on my own, it's actually how I structure my whole config (https://github.com/Infinisil/system), and I do have loads of things enabled, so I guess it makes sense that it's a bit longer. The fact that a minimal system already takes almost 3 seconds to evaluate is what's annoying me here, and the fact that it increases over time! |
Just yesterday I brainstormed some ideas for a NixOS module rewrite with performance (and security) in mind which could solve this problem. It would also be almost backwards compatible and integrate well with Flakes too. It would take a while to implement however, not sure how I can find the time for it. I think such a rewrite might be our best bet of fixing this unfortunately. |
@infinisil I was dissecting your config, here is what I found:
So far my conclusions are:
Minimal set of modules for `orakel`
|
This comment has been minimized.
This comment has been minimized.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Just an anecdote, but evaluating my not particularly big NixOS configuration defined with flakes takes over 1 GB of RAM and ~20 seconds just to evaluate on my aarch64 device... If NixOS is to be usable on all devices, this is a major blocker IMO. |
Without going into making RFCs, there is a hack which is possible to reduce the amount of imported modules. Previously, NixOS modules used to be evaluated twice. A first time to compute the The hack I am thinking off, is that we could make a list similar to Another option, would be to dig |
@nbp I'm guessing this would only help if the system doesn't have the manual enabled though? |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
So I created a very minimal module list (way smaller than @danbst one) and it evals in 3.2 seconds. So seems we had a regression in nixos module eval performance recently :( Eval times doubled whilst the module list is smaller https://github.com/arianvp/lolmin/actions/runs/9120699581/job/25078546117 |
Oh of course i dont know what machine they used.... so my statement is kinda useless. However the minimal module list is still 2x faster than non-minimal. Full experiment + code is here: |
I'm opening this issue to track some things I've done relating to the continuous slowdown of nixos evaluation performance over time.
My system takes 13 seconds to evaluate (
nix-instantiate '<nixpkgs/nixos>' -A system
), which is too long!What I've done
Measurements
commit (release): instantiation time for demo.nix (
time nix-instantiate
test.nix-A system
, number of options (cat $(nix-build --no-out-link nixos/release.nix -A options)/share/doc/nixos/options.json | jq 'keys[]' -r | wc -l
), number of modules (nix-instantiate --eval -E 'builtins.length (import nixos/modules/module-list.nix)'
)a6caed5 (19.03): 2.74, 7630, 887
37694c8 (18.09): 2.40, 6937, 831
c8c521f (18.03): 2.25, 6280, 772
3ba3d8d (17.09): 1.62, 5741, 737
2c1838a (17.03): 1.22, 5114, 669
52ef8b0 (16.09): 0.73, 4234, 590
dda40aa (16.03): 0.65, 3624, 535
cc7c261 (15.09): 0.62, 3131, 493
7708224 (14.12): 0.60, 2451, 407
module count has increased by 118%
option count has increased by 211%
average option count per module has increased from 6.0 to 8.6
time has increased by 356%
Turning off the options manual generation
I was hoping that the reason for the regression is due to all options being evaluated strictly, so here's my branch (probably could've just turned off the manual but oh well). Results: Decreases evaluation time by a constant of ~1 second, so my system now only takes 12 seconds.. Not good enough. See branch for a bit more info.
Alternatively, earlier, offloading option generation to build time
Branch here. Results: Mostly failed, recursive Nix doesn't work very well and it brings a lot of limitations with it. See branch for a bit more info.
Theory / Conclusion
Being out of time for now, I feel like the problem is a combination of:
enable
options (and similar ones). Theseenable
options are defined for every module and they need to be evaluated regardless of whether you use the module or not, so this adds up with the ~1110enable
options we have in 19.03, and ever increasingSo this would also mean that the number of options a module defines has only very little influence on evaluation time (in contrast to what I've thought and told other people for some time now)! Of course the manual penalty of 1s is still there, but that's almost negligible.
Future Work
Related
Pings
@edolstra @nbp @Profpatsch @rycee @aanderse @Ekleog @Ericson2314
The text was updated successfully, but these errors were encountered: