I’ve been a NixOS user for over 2 years and with the growth of my NixOS configuration, I found that my system rebuild is becoming slower (takes around 3-5 mins and a lot of memory to just evaluate my system top-level derivation) but I can’t figure out the reason behind it. I’ve followed the advice in other posts to avoid instantiating many nixpkgs but it still doesn’t help.
I’m wondering if there’s a way that I could get more verbose statistics to help to find which part causes the slow rebuild. I would appreciate any ideas and advice.
Yes I did. The --verbose flag just shows what it is currently building. But my problem is that the first step to evaluate the system.build.toplevel derivation takes most of time and memory. It hasn’t started building anything yet. Building itself is fast enough comparing to evaluation
That’s also why even a very small change can take nearly the same amount of time.
I don’t think so. But I’m doing something like imports = listFiles ./modules, where listFiles calls builtins.readDir to import all files in modules directory, though I don’t think it needs extra instantiation as /etc/nixos will always be added to store.
Yeah I also doubt it’s due to IFD but I just couldn’t find it in my config files. Is there a way to show the evaluation traces so I can find out what really happened?
Unfortunately, there’s no difference in performance after enabling the option. I also tried nix --extra-experimental-features nix-command build /etc/nixos#nixosConfigurations."xxx".config.system.build.toplevel --no-allow-import-from-derivation --verbose --dry-run but still no difference.
Each nixos-container is its own nixos config and eval time would therefore grow linearly. Could you try disabling all the nixos-containers and evaling the config? (Eval is enough, no need to build.)
It seems these containers are indeed the real culprit. The evaluation is around 5x faster and uses much less memory after disabling them!
But nixos-containers are really convenient to run services in isolated environments. Is there any way to speed them up? The config of each container is usually just enabling a service.
If you are just worried that your service is not isolated enough, you can add additional hardening features to your systemd service. I am certainly not saying that nixos containers cannot be used, but they may be a bit too heavy for this scenario.
I still think systemd-nspawn fits my use cases better, especially for the network isolation. It’s hard (though still doable) to set up the namespace and join them using veths and bridge just using systemd service config.
Or are you suggesting that I configure systemd-nspawn from scratch? (I haven’t tried it yet but maybe it’s doable, but I need to figure out how to convert nix config to systemd-nspawn config)