How do I fix this
When rebuilding, Nix downloads pre-built packages, and if pre-built downloads are not available, then it builds them on your computer, which is probably what’s causing 100% CPU usage. You can avoid this by checking your config and finding if you added things which do not have binary cache. If you can’t avoid building the packages, you can also configure Nix to only use X amount of cores and build X amount of packages at a time, so you could make it so that only 1 core is 100% and not all 16 (but idk how much that will help with fan noise and power consumption).
Can you please tell me how to do that? 1 core might take too long so I wanna use half the cores. I just want to be able to use my laptop while it’s buildings. The freezing is unacceptable
As noted by @waffle8946, you can configure nix to reduce the number of concurrent nix builds and reduce how parallel each nix build is.
Additionally, the desktop freezes are probably because your system has run out of memory because too many builds are running at once.
And as noted by @ChocolateLoverRaj, if you are getting NixOS from a release channel then most of your system should just get copied in from cache.nixos.org
. If not, then try to figure out what it’s building and why it can’t be substituted from a binary cache.
I think that answers your question.
But I would like to add that if your laptop gets really hot, it’s not just nix that will cause problems for you. Any program that can use all CPU cores is likely to be a problem.
Try using stress
and s-tui
to load up your computer and see what happens.
My laptop was running too hot for my liking when plugged in to an AC charger. The reason was that I had the cpufreq scaling governor set to “performance,” among other things. If you’re using GNOME, check the power management settings, and perhaps try “balanced” or something like that.
Your system might freeze due to OOM and/or “swap death”, or perhaps even because the CPU is running too hot.
My laptop was also freezing, seemingly at random. I disabled intel turbo boost and that seems to have stopped the freezes, but I’m not yet sure whether turbo boost alone was the cause.
Things you can do to delay onset of a frozen system due to OOM are:
- Make sure you have configured a swap device/file. This won’t help if memory is exhausted but seems to help when memory is tight.
- Use zram:
zramSwap.enable = true;
- Configure
services.earlyoom
to kill processes before your system gets swamped.
The other thing I have been trying to do for my system is to make the desktop more responsive during nix builds by reducing the relative priority of nix-daemon
using systemd directives CPUSchedulingPolicy=batch
and IOSchedulingClass=best-effort
. Unfortunately this doesn’t seem to have helped much.
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.
};
Yeah, no, this is definitely memory pressure, the device getting hot won’t affect performance anywhere near as much as literally eating all available memory, it looks like both swap space and main memory are at capacity in that screenshot. Little memory use tweaks won’t help here, you’re just scheduling way too many builds.
If your configuration correctly uses the cache, you should never get into this situation.
If it doesn’t use it correctly, this likely means you’re also not getting updates at the schedule you intend, and potentially not at all in the future. You’re also still going to waste hours on builds you don’t need to do even if you reduce build concurrency, fixing what you did to not be able to use the cache should be your main priority.
This usually means you’re using the wrong channel or cargo culted a way of pinning nixpkgs that ends up pulling in a branch that isn’t built by hydra. You’ll have to share your channels or code for help fixing that.
Yes my memory (32GB) and swap (8GB) get used up 100%. I even tried increasing my swap to 32GB, it still used everything all up and froze.
This is my flake.nix
{
description = "Flake for Personal Computer with Home Manager enabled";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
self,
nixpkgs,
home-manager,
...
}@inputs:
{
nixosConfigurations = {
nixos = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = {
inherit inputs;
};
modules = [
./configuration.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.elias = import ./home/home.nix;
}
];
};
};
};
}
That looks right, do you use --impure
? Any overrides or overlays to mention? When you rebuild your system, which package names pop up among the things being rebuilt?
no i’m not using impure. no overrides or overlays. to give you context, i just switched back to nixos after using pop os and i’m trying to rebuild my entire system from scratch in 1 go.
That should still only result in a tiny number of things being built, almost everything should be resolving from the cache, the rest will be configuration files that take next to no time or space to build, certainly not 40+GB’s worth of memory in either case.
Did you nix flake update
before this? If that’s not the issue, could you share the rest of your configuration?
Please also check your nix.conf
.
The following command-line args may help correct any problems. See the nix.conf
manual for details.
The options cores
and max-jobs
will at least ensure that your machine isn’t maxed out from the load.
The nix build --recreate-lock-file
arg will make sure that we are actually using the nixos-unstable
branch of nixpkgs as specified by the flake input url.
The other options should hopefully ensure that the binary cache is used for your nixos system build.
nix \
--option substitute true \
--option fallback false \
--option substituters https://cache.nixos.org/ \
--trusted-public-keys cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= \
--option extra-trusted-users elias \
--option cores 1 \
--option max-jobs 2 \
build \
--recreate-lock-file \
.#nixosConfigurations.nixos.config.system.build.toplevel
Thanks for the tip @kjetil.