What is the best option for power management?

NixOS offers a lot of power management tools

  • builtin
  • power-profiles-daemon (often required by desktop environments?)
  • TLP
  • tuned (to be made)

additionally there is system76-scheduler which has a lot of configuration options and might be power related?

the builtin options are a bit too minimalistic, for example there seems to be no difference between AC and Battery?

TLP seems to conflict with ppd, which might be required by desktop environments.

This is my current config

{ config, lib, pkgs, ... }:
{
    ### Intel
    hardware.intel-gpu-tools.enable = true;

    ### NixOS power management
    powerManagement = {
        enable = true;
        powertop.enable = true;
        cpuFreqGovernor = "schedutil"; #power, performance, ondemand
    };

    ### system76
    hardware.system76.power-daemon.enable = true;
    services.system76-scheduler.enable = true;
    #services.system76-scheduler.settings.processScheduler.enable = true; #default

    #services.power-profiles-daemon.enable = true; #ppd, not default
}
1 Like

I don’t want to charge my Lenovo battery to 100%, so I need tlp for that.

Here is my configuration:

{
  config,
  lib,
  vars,
  ...
}: let
  cfg = config.custom;
  hasBattery =
    lib.any (x: lib.strings.hasPrefix "BAT" x)
    (builtins.attrNames (builtins.readDir "/sys/class/power_supply"));
in {
  options.custom = {
    battery.enable = lib.mkOption {
      default = hasBattery;
      description = "Enable better battery support";
      type = lib.types.bool;
    };
  };

  config = lib.mkIf cfg.battery.enable {
    powerManagement.powertop.enable = true; # enable powertop auto tuning on startup.

    services.system76-scheduler.settings.cfsProfiles.enable = true; # Better scheduling for CPU cycles - thanks System76!!!
    services.thermald.enable = true; # Enable thermald, the temperature management daemon. (only necessary if on Intel CPUs)
    services.power-profiles-daemon.enable = false; # Disable GNOMEs power management
    services.tlp = {
      enable = true; # Enable TLP (better than gnomes internal power manager)
      settings = {
        CPU_BOOST_ON_AC = 1;
        CPU_BOOST_ON_BAT = 1;
        CPU_HWP_DYN_BOOST_ON_AC = 1;
        CPU_HWP_DYN_BOOST_ON_BAT = 1;
        CPU_SCALING_GOVERNOR_ON_AC = "performance";
        CPU_SCALING_GOVERNOR_ON_BAT = "powersave";
        CPU_ENERGY_PERF_POLICY_ON_AC = "performance";
        CPU_ENERGY_PERF_POLICY_ON_BAT = "balance_power";
        PLATFORM_PROFILE_ON_AC = "performance";
        PLATFORM_PROFILE_ON_BAT = "balanced";
        START_CHARGE_THRESH_BAT0 = 75;
        STOP_CHARGE_THRESH_BAT0 = 81;
      };
    };
  };
}

1 Like

I haven’t done in depth testing but when recently started to use KDE I had to throw out TLP.
So far I haven’t noticed that much of a difference in power consumption.

I miss a bit the flexibility of TLP however.

There is also GitHub - AdnanHodzic/auto-cpufreq: Automatic CPU speed & power optimizer for Linux

1 Like

There also is an Oracle project to auto tune the system. I am worried that all these things dont work well together. The system76 stuff also autotunes stuff.

I could ask them what their software covers and what not.

The nixos builtin stuff is quite basic, and unlikely to cause problems with other implementations as far as I am aware. It pretty much just enables suspend. See its implementation here.

Beyond that, pretty much everything listed conflicts with everything else listed.

For example, TLP’s docs recommend disabling thermald and also notes that it conflicts with power-profiles-daemon

Tuned would seem to be the most advanced one available, and has been chosen by fedora. There is a WIP implementation of tuned for nixos at, tuned: init at 2.24.0 by getchoo · Pull Request #357480 · NixOS/nixpkgs · GitHub. But it seems to have stalled.

So I would say just pick one of (tlp, auto-cpufreq, power-profiles-daemon, system76-power), try it for a while and then try others if you want.

It seems to be safe to enable powertop in addition to any of the others, but I am not sure.

system76-scheduler is a scheduler rather than a power management tool. It can have theoretical impacts on performance and energy use, but it does so by changing how programs are scheduled to be ran rather than tweaking hardware settings. So it can be safely enabled in addition to any others.

1 Like

This is only half-true. Other modules depend on that setting, too. E.g. most DEs enable upower if it is set, and I know some other things which may interfere with the other daemons you mention are set elsewhere too: nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix at 8b6089d59839b64e4df771f3aaec22650d923eb7 · NixOS/nixpkgs · GitHub

Personally I’ve had pretty reasonable battery performance since enabling upower - WMs don’t usually enable it. I’ve also had to manually fix nvidia power settings since the udev rules don’t actually work.

I don’t think there’s a one-size-fits-all “best” solution. You’ll have to understand what everything does and experiment to get there - which is quite hard given that how you use your laptop on a given day will change what things do and don’t work. Figuring out how you can measure each device’s power usage and whether stuff could be turned off that isn’t is a good start. Adaptive display brightness is also worth looking at. Tuning CPU governors ad-hoc with userspace daemons seems like a rather down-the-line kind of optimization.

do you use upower together with ppd?

1 Like

I havent enabled upower manually. I thought KDE would depend on ppd, which I have enabled.

This is my current config

### Intel
    hardware.intel-gpu-tools.enable = true;

    ### NixOS power management
    powerManagement = {
        enable = true;
        #cpufreq.min = 800000;
        #cpufreq.max = 2200000;
        powertop.enable = true;
        #powerUpCommands =
        cpuFreqGovernor = "schedutil"; #power, performance, ondemand
    };

hardware.system76.power-daemon.enable = true;

    services.power-profiles-daemon.enable = true; #ppd, not default