Here’s the config I ended up with. I haven’t done any thorough testing to make sure it works as intended, but all the knobs for tweaking are there.
Its using both nix.daemonCPUSchedPolicy and systemd resource restrictions, which is probably superfluous. Systemd CPU quota and memory limitations confirmed working, but haven’t been able to verify CPU priority
# - Reduce impact of background upgrades on interactive performance
# Method 1: (not sure if the priority of the systemd service propegates to the actual build process)
# ref https://github.com/NixOS/nixpkgs/issues/77971
# and https://unix.stackexchange.com/questions/494843/how-to-limit-a-systemd-service-to-play-nice-with-the-cpu/495013#495013
systemd.services.nixos-upgrade.serviceConfig = {
CPUWeight = "20"; # defaults to 100 for all processes. Lower value means lower priority. This is a arbitrary weight integer.
CPUQuota = "85%"; # absolute limit on how much CPU time is granted even if nothing else is going on. This is a percent value.
IOWeight = "20"; # IOWeight is much the same as CPUWeight
# https://unix.stackexchange.com/questions/436791/limit-total-memory-usage-for-multiple-instances-of-systemd-service
# This doesn't prevent it from using swap
MemoryHigh = "2048M";# original 500MB => Actual usage 500 MB RAM + 1.3gb SWAP
MemoryMax = "3072M";
#MemorySwapMax = "0";
};
# Method 2: https://search.nixos.org/options?channel=24.11&show=nix.daemonCPUSchedPolicy&from=0&size=50&sort=relevance&type=packages&query=nix.daemon
nix={
daemonCPUSchedPolicy = "idle"; # the idle policy may greatly improve responsiveness of a system performing expensive builds
daemonIOSchedClass = "idle"; #
daemonIOSchedPriority = 7; # N/A: With "idle", priorities are not used in scheduling decisions. range 0 (high) to 7 (low). default 4.
};