Evaluating derivation getting slow

Hello, my nixos-rebuilds now spend over 40 seconds on just ‘evaluating derivations’. This seems rather slow, at least when trying out changes.

Can anyone suggest what I’m doing wrong that’s leading to it taking so much time? I could try converting imports to modules, or reducing the inputs, or fewer overlay changes, but I’m not sure what will actually make a difference.

My nix config is at: GitHub - KenMacD/etc-nixos

I’m using rebuilding with:

nixos-rebuild switch --use-remote-sudo --flake 'path:...#ke' --verbose

I’ve been testing and get the same time with:

nix eval --raw 'path:...#nixosConfigurations."ke".config.system.build.toplevel' --no-eval-cache

Having a lot of overlays and inputs can definitely lead to this situation unfortunately. You can try reducing those if possible, but yes, nix is slow, and eval is single-threaded. 40s isn’t terrible, my eval peaked at 30s, and I know of one other person whose config eval takes 6 minutes.

Also I did notice you have several nixpkgs instances, if you can cut those down that would help.

3 Likes

Okay, thanks. It’d be nice if this was faster, but at least if I’m not the only one then perhaps I’m not doing anything particularly wrong.

Mine evaluating derivation around 6 min. My sad part of lovely nix ecosystem. Still trying to figure out. Tried various changes (nix related) and still trying, but thanks @waffle8946 mentioning inputs, overlays.

{
  description = "NixOS config";
  inputs = {
    systems.url = "github:nix-systems/x86_64-linux";
    nixpkgs.url = "nixpkgs/nixos-unstable";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    nix-colors.url = "github:misterio77/nix-colors";
    nixos-hardware.url = "github:NixOS/nixos-hardware/master";
    rust-overlay = { url = "github:oxalica/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; };
    nur.url = "github:nix-community/NUR";
    dmenu-flexipatch = { url = "github:bakkeby/dmenu-flexipatch"; flake = false; };
    dwm-flexipatch = { url = "github:bakkeby/dwm-flexipatch"; flake = false; };
    st-flexipatch = { url = "github:bakkeby/st-flexipatch"; flake = false; };
    tabbed-flexipatch = { url = "github:bakkeby/tabbed-flexipatch"; flake = false; };
    musnix = { url = "github:musnix/musnix"; };
    LS_COLORS = { url = "github:trapd00r/LS_COLORS"; flake = false; };
    neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
    vim-log-highlighting = { url = "github:MTDL9/vim-log-highlighting"; flake = false; };
    vim-interestingwords = { url = "github:lfv89/vim-interestingwords"; flake = false; };
    nvim-lsp-file-operations = { url = "github:antosha417/nvim-lsp-file-operations"; flake = false; };
    lobster.url = "github:justchokingaround/lobster";
    neotest-zig = { url = "github:lawrence-laz/neotest-zig"; flake = false; };
    nvim-dap-vscode-js = { url = "github:mxsdev/nvim-dap-vscode-js"; flake = false; };
    neotest-playwright = { url = "github:thenbe/neotest-playwright"; flake = false; };
    sxhkd-vim = { url = "github:kovetskiy/sxhkd-vim"; flake = false; };
    persistent-breakpoints = { url = "github:Weissle/persistent-breakpoints.nvim"; flake = false; };
    # rustaceanvim = { url = "github:mrcjkb/rustaceanvim"; };
  };
  outputs =
    { nixpkgs, home-manager, nixos-hardware, nix-colors, dmenu-flexipatch, dwm-flexipatch, st-flexipatch, tabbed-flexipatch, ... } @ inputs:
    let
      system = "x86_64-linux";
      pkgs = nixpkgs.legacyPackages.${system};
      include = p: with builtins;
        map (f: "${p}/${f}") (filter (n: !isNull (match ".*+\.nix" n)) (attrNames (readDir p)));
      overlays =
        with inputs; [
          rust-overlay.overlays.default
          nur.overlay
          neovim-nightly-overlay.overlays.default
          (_final: prev: with prev; {
            inherit LS_COLORS;
          })
          (_final: prev:
            let
              inherit (prev.vimUtils) buildVimPlugin;
            in
            {
              vimPlugins = with inputs;
                prev.vimPlugins
                // {
                  vim-log-highlighting = buildVimPlugin {
                    name = "vim-log-highlighting";
                    src = vim-log-highlighting;
                    meta = { homepage = "https://github.com/MTDL9/vim-log-highlighting"; };
                  };
                  vim-interestingwords = buildVimPlugin {
                    name = "vim-interestingwords";
                    src = vim-interestingwords;
                    meta = { homepage = "https://github.com/lfv89/vim-interestingwords"; };
                  };
                  nvim-lsp-file-operations = buildVimPlugin {
                    name = "nvim-lsp-file-operations";
                    src = nvim-lsp-file-operations;
                    meta = { homepage = "https://github.com/antosha417/nvim-lsp-file-operations"; };
                  };
                  neotest-zig = buildVimPlugin {
                    name = "neotest-zig";
                    src = neotest-zig;
                    meta = { homepage = "https://github.com/lawrence-laz/neotest-zig"; };
                  };
                  nvim-dap-vscode-js = buildVimPlugin {
                    name = "nvim-dap-vscode-js";
                    src = nvim-dap-vscode-js;
                    meta = { homepage = "https://github.com/mxsdev/nvim-dap-vscode-js"; };
                  };
                  neotest-playwright = buildVimPlugin {
                    name = "neotest-playwright";
                    src = neotest-playwright;
                    meta = { homepage = "https://github.com/thenbe/neotest-playwright"; };
                  };
                  sxhkd-vim = buildVimPlugin {
                    name = "sxhkd-vim";
                    src = sxhkd-vim;
                    meta = { homepage = "https://github.com/kovetskiy/sxhkd-vim"; };
                  };
                  persistent-breakpoints = buildVimPlugin {
                    name = "persistent-breakpoints";
                    src = persistent-breakpoints;
                    meta = { homepage = "https://github.com/Weissle/persistent-breakpoints.nvim"; };
                  };
                };
            })
        ];
    in
    {

      formatter."${system}" = pkgs.nixpkgs-fmt;
      nixosConfigurations = {
        dell = nixpkgs.lib.nixosSystem {
          # DELL XPS 7590
          inherit system;
          # specialArgs = nixosModules.args._module.args;
          specialArgs = {
            inherit include;
            inherit dmenu-flexipatch;
            inherit dwm-flexipatch;
            inherit st-flexipatch;
            inherit tabbed-flexipatch;
          };
          modules = [
            # musnix.nixosModules.musnix
            {
              nixpkgs.overlays = overlays;
              nix.registry = {
                nixpkgs.flake = inputs.nixpkgs;
                home-manager.flake = inputs.home-manager;
                # nixos = { to = { type = "git"; url = "file:///etc/nixos"; }; };
              };
              environment.systemPackages = [
                # inputs.lobster.packages.${system}.lobster
                # inputs.rustaceanvim.packages.${system}.codelldb
              ];
            }
            ./configuration.nix
            ./_dell.nix
            ./_audio.nix
            nixos-hardware.nixosModules.dell-xps-15-7590
            nixos-hardware.nixosModules.dell-xps-15-7590-nvidia
            nixos-hardware.nixosModules.common-hidpi
            home-manager.nixosModules.home-manager
            {
              home-manager = {
                useGlobalPkgs = true;
                useUserPackages = false;
                users.root = import ./home.nix;
              };
              home-manager.extraSpecialArgs = {
                inherit inputs;
                inherit include;
                inherit nix-colors;
              };
            }
          ];
        };

        pc = nixpkgs.lib.nixosSystem {
          # PC B450 AORUS M
          inherit system;
          specialArgs = {
            inherit include;
            inherit dmenu-flexipatch;
            inherit dwm-flexipatch;
            inherit st-flexipatch;
            inherit tabbed-flexipatch;
          };
          modules = [
            {
              nixpkgs.overlays = overlays;
              nix.registry = {
                nixpkgs.flake = inputs.nixpkgs;
                home-manager.flake = inputs.home-manager;
                # nixos = { to = { type = "git"; url = "file:///etc/nixos"; }; };
              };
              environment.systemPackages = [
                # lobster.packages.${system}.lobster
              ];
            }
            ./configuration.nix
            ./_pc.nix
            nixos-hardware.nixosModules.common-cpu-amd-pstate
            nixos-hardware.nixosModules.common-gpu-nvidia-nonprime
            nixos-hardware.nixosModules.common-hidpi
            home-manager.nixosModules.home-manager
            {
              home-manager = {
                useGlobalPkgs = true;
                useUserPackages = false;
                users.root = import ./home.nix;
              };
              home-manager.extraSpecialArgs = {
                inherit inputs;
                inherit include;
                inherit nix-colors;
              };
            }
          ];
        };
      };
    };
}

wall of flake inputs

I can’t imagine what could be slowing down your eval here mate…

On a more serious note: Put some numbers behind that intuition. You can sort of infer where Nix spends most of its eval time by adding a few -vvvvs and looking at the timing. Is it fetching flake inputs stuff? What files does it spend the most time evaluating?

What also helps is disabling optional things and comparing eval time. Keep in mind that you don’t need to build anything, only eval. Producing configs that eval but would break your workflow or requirements for comparison’s sake would be totally fine.

My first suspect would be home-manager and vim config. Disable those and see what it does to your eval time.

Make sure the eval cache does not interfere with your measurements though.

Instead of weaving through all the inputs via specialArgs, rely on the overlays only. Or at least mainly.

SpecialArgs with “inputs” makes it easy and tempting to access upstream flake packages without overlays, and thus too easy to add more and more nixpkgs evaluations. Also, use the overlay’d nixpkgs to do the module evaluation as well.

A trick, not always possible, is to import flakes w/flake=false and grab the overlays manually. This can fail if the upstream author didnt design them correctly, but can serve as a check to make sure you are not doing multiple Nixpkgs evaulations.

Lastly, it is sometimes nicer to manage your system independently from home-manager. They can be coupled or decoupled. I find it nice to manage them on their own, only pay the upgrade/eval cost in a more fine-grained manner.

3 Likes

After some minor changes eliminated specialArgs especially “inputs” (which wasn’t really needed). nixos-rebuild now takes 2min instead of 6min earlier before, so im quite happy with if. Thanks

1 Like

Hi! Do you have an example of the changes you made? I’m also trying to reduce my startup time but the specialArgs inputs is pretty tightly woven into my config (based on GitHub - Misterio77/nix-starter-configs: Simple and documented config templates to help you get started with NixOS + home-manager + flakes. All the boilerplate you need!) and I’m not sure what I’d need to do to start accessing imported stuff (like home-manager) directly.

Thanks!

Startup? I had issues with nixos-rebuild time.
Now specialArgs inputs used just in one imported module.
My current /etc/nixos/flake.nix:

flake.nix
{
  inputs = {
    nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.0.tar.gz";
    templates.url = "github:NixOS/templates";
    dev-templates.url = "https://flakehub.com/f/the-nix-way/dev-templates/0.1.283.tar.gz";
    nixos-hardware.url = "github:NixOS/nixos-hardware/master";
    nixos-generators = {
      url = "github:nix-community/nixos-generators";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    audio.url = "./audio";
    fzf.url = "./fzf";
    git.url = "./_git";
    go.url = "./go";
    lf.url = "./lf";
    lib.url = "./lib";
    LS_COLORS.url = "./LS_COLORS";
    manix.url = "./manix";
    matrix.url = "./matrix";
    suckless.url = "./suckless";
    pistol.url = "./pistol";
    rust.url = "./rust";
    vim.url = "./vim";
    wayland.url = "./wayland";
    zsh.url = "./zsh";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    nix-colors.url = "github:misterio77/nix-colors";
    nix-index-database.url = "github:nix-community/nix-index-database";
    nix-index-database.inputs.nixpkgs.follows = "nixpkgs";
    firefox.url = "./firefox";
    # aldale.url = "./aldale";
    aiva.url = "./aiva";
    lua.url = "./lua";
    nur.url = "github:nix-community/NUR";
    nur.inputs.nixpkgs.follows = "nixpkgs";
  };
  outputs =
    { nixpkgs, ... }@inputs:
    let
      system = "x86_64-linux";
      # pkgs = nixpkgs.legacyPackages.${system};
      pkgs = import nixpkgs {
        inherit system;
        overlays = [
          inputs.nur.overlays.default
          # inputs.firefox.overlays.default
        ];
      };
      commonModules = with inputs; [
        { environment.systemPackages = [ pkgs.git ]; }
        inputs.audio.nixosModules.mpd
        inputs.audio.nixosModules.production
        inputs.audio.nixosModules.pipewire
        inputs.firefox.nixosModules.default
        inputs.fzf.nixosModules.default
        inputs.git.nixosModules.default
        inputs.lf.nixosModules.default
        inputs.lib.nixosModules.default
        inputs.LS_COLORS.nixosModules.default
        inputs.go.nixosModules.default
        inputs.manix.nixosModules.default
        inputs.matrix.nixosModules.default
        inputs.pistol.nixosModules.default
        inputs.rust.nixosModules.default
        inputs.suckless.nixosModules.default
        inputs.vim.nixosModules.default
        inputs.vim.nixosModules.plugins.default
        inputs.zsh.nixosModules.default
        # inputs.aldale.nixosModules.default
        # inputs.aiva.nixosModules.default
        inputs.lua.nixosModules.default
        # inputs.wayland.nixosModules.default
        # inputs.firefox.nixosModules.pass.default
        {
          imports =
            with inputs.lib.packages."${system}".lib;
            (
              [
                ./lnav
                ./systemd/remote-touchpad.nix
                ./virt/virtualbox.nix
                ./wallpaper
              ]
              ++ i ./config
              ++ i ./network
              ++ i ./programs
              ++ idash ./services
            );
        }
        inputs.home-manager.nixosModules.home-manager
        {
          home-manager = {
            useGlobalPkgs = true;
            useUserPackages = true;
            users.root = {
              home.stateVersion = "23.05";
              home.username = "root";
              home.homeDirectory = "/root";
              home.enableNixpkgsReleaseCheck = false;
              manual.json.enable = true;
              colorScheme = inputs.nix-colors.colorSchemes.gruvbox-dark-medium;
              services.mpris-proxy.enable = true; # https://specifications.freedesktop.org/mpris-spec/latest/
              services.blueman-applet.enable = true;
              imports =
                with inputs.lib.packages."${system}".lib;
                [
                  inputs.fzf.nixosModules.home
                  inputs.git.nixosModules.home
                  inputs.lf.nixosModules.home
                  inputs.vim.nixosModules.home
                  inputs.vim.nixosModules.plugins.home
                  inputs.zsh.nixosModules.home
                  inputs.firefox.nixosModules.main
                  inputs.firefox.nixosModules.extensions
                  inputs.firefox.nixosModules.basic
                  inputs.firefox.nixosModules.dns
                  inputs.firefox.nixosModules.devtools
                  inputs.firefox.nixosModules.newtabpage
                  inputs.firefox.nixosModules.urlbar
                  inputs.firefox.nixosModules.telemetry
                  inputs.firefox.nixosModules.tabs
                  inputs.firefox.nixosModules.privacy
                  inputs.firefox.nixosModules.media
                  # inputs.firefox.nixosModules.vaapi
                  inputs.nix-colors.homeManagerModules.default
                  inputs.nix-index-database.hmModules.nix-index
                  inputs.lua.nixosModules.common.home
                  inputs.lua.nixosModules.vim.home
                  inputs.lua.nixosModules.neovim.home
                ]
                ++ i_ ./config
                ++ i_ ./programs
                ++ i_ ./services
                ++ i_ ./lua;
            };
          };
        }
      ];
    in
    {
      packages.x86_64-linux = {
        iso = inputs.nixos-generators.nixosGenerate {
          system = system;
          format = "iso"; # https://github.com/nix-community/nixos-generators#supported-formats
          modules = [ ];
        };
        vbox = inputs.nixos-generators.nixosGenerate {
          system = system;
          format = "virtualbox";
        };
      };
      checks."${system}".default = pkgs.testers.runNixOSTest {
        name = "self";
        nodes.machine = { ... }: { };
        testScript = builtins.readFile ./flake.test.py;
      };
      devShells."${system}".default = pkgs.mkShell { };
      formatter."${system}" = pkgs.nixfmt-rfc-style;
      nixosConfigurations.dell = nixpkgs.lib.nixosSystem {
        modules = commonModules ++ [
          # inputs.nixos-hardware.nixosModules.common-hidpi
          # {
          #   boot.kernelParams = [
          #     "i915.enable_guc=2"
          #   ];

          #   hardware.intelgpu.vaapiDriver = "intel-media-driver";
          # }
          inputs.nixos-hardware.nixosModules.dell-xps-15-7590-nvidia
          ./bluetooth
          ./dell.nix
        ];
        specialArgs = { inherit inputs; };
      };
      nixosConfigurations.pc = nixpkgs.lib.nixosSystem {
        modules = commonModules ++ [
          inputs.nixos-hardware.nixosModules.common-cpu-amd-pstate
          inputs.nixos-hardware.nixosModules.common-gpu-nvidia-nonprime
          inputs.nixos-hardware.nixosModules.common-hidpi
          ./pc.nix
        ];
        specialArgs = { inherit inputs; };
      };
    };
}