Post

Understading Linux CPI Frequency Scaling Governors

Understading Linux CPI Frequency Scaling Governors

Modern processors can run at different speeds (and voltages) depending on demand. Running at higher clock frequencies makes the CPU perform more operations per second but also draws more power and generates more heat. CPU frequency scaling (often part of Dynamic Voltage and Frequency Scaling, DVFS) is the mechanism that adjusts the processor’s speed on the fly to balance performance and energy usage. In periods of low demand, scaling down the CPU frequency conserves power (great for battery life and lower temperatures); when high performance is needed, scaling up ensures the work gets done faster. The Linux kernel’s CPUFreq subsystem provides this capability by exposing multiple “governors” – each is a policy/algorithm deciding what frequency the CPU should run at, based on certain criteria. In short, CPU frequency scaling is about dynamically finding the right CPU speed for the current workload, so your system isn’t always running at full throttle (wasting energy) or stuck slow when you need speed.

Overview of CPU Frequency Scaling Governors

A CPUFreq governor is an algorithm in the kernel that selects the CPU’s operating frequency (within allowed min/max ranges) according to a specific policy. Linux comes with several built-in governors, each with a different strategy ranging from always running at a fixed frequency to dynamically adjusting based on system load. Below is an overview of the main governors available on Ubuntu and what they do:

  • performance - This governor sets the CPU statically to the highest frequency possible (within the CPU’s allowed range) at all times. In other words, it keeps the processor running at full speed. This yields maximum computing power and the lowest latency for responding to new tasks. The downside is that the CPU never slows down when idle or lightly used, so it may waste power and run hotter when full speed isn’t needed. The performance governor is ideal for use-cases where top performance is crucial and power consumption is a secondary concern (for example, on a server where throughput is paramount, or a desktop during a gaming session or audio production). It’s essentially “pedal to the metal” – great for speed, not so much for efficiency.
  • poversave - This is essentially the opposite of “performance”. The “powersave” governor sets the CPU statically to the lowest frequency available. In effect, it locks the processor at its minimum speed (often a low P-state) and keeps it there. This can significantly reduce power usage and heat output – useful for maximizing battery life or a silent running system – but at the obvious cost of lower performance whenever the CPU could be running faster. In “powersave” mode, the CPU will not automatically increase speed even under load (on traditional ACPI systems), so heavy tasks will run noticeably slower. This governor is useful if you need to force the lowest power operation (for example, to prevent thermal issues or stretch battery as long as possible), but it is generally not for everyday use when performance is needed. (Note: On modern Intel/AMD platforms with advanced power management, the “powersave” label can be misleading – see the section on P-State drivers below.)
  • ondemand - The ondemand governor is a dynamic, load-responsive governor. It monitors CPU usage and adjusts the frequency according to current system load. When load increases, “ondemand” will quickly ramp the CPU up to higher frequencies; when the load drops, it will scale the CPU down. In fact, the algorithm typically jumps to maximum frequency as soon as the CPU load crosses a certain threshold, ensuring prompt response to demand. As the system becomes idle, it may step the frequency back down to save power. Ondemand’s philosophy is to provide a good balance between performance and power saving – run at full speed when the CPU is busy, but drop to low speed when idle. This was for a long time the default governor on many Linux systems because it offers a reasonable compromise for most users. Under the hood, ondemand uses a kernel thread (workqueue) that periodically checks CPU utilization at a defined sampling rate (every few milliseconds). If the recent CPU usage is above an up-threshold (e.g. 95%), ondemand will immediately set the CPU to the max frequency; if usage is well below a down-threshold, it will decrease the frequency. These thresholds and the sampling interval are tunable via sysfs (for example, ondemand/up_threshold, ondemand/sampling_rate, etc.) so advanced users can tweak how aggressive or conservative the scaling is. The ondemand governor works best on systems where workload can spike and drop, providing performance when needed but saving energy when the CPU isn’t busy. (It does assume the CPU can transition frequencies quickly – modern CPUs can, usually on the order of microseconds.)
  • censervative - This governor is also dynamic and load-based, similar to ondemand, but it behaves more gradually (hence the name conservative). Instead of jumping straight to 100% frequency on any moderate load, the conservative governor increases and decreases the CPU speed in small steps. It might, for example, step up the frequency one level at a time as load increases, rather than going immediately to max. Likewise, it steps down gradually when load decreases. The idea is to avoid rapid frequency swings which might draw bursts of power – favouring a smoother change that can be gentler on battery or power-sensitive systems. By default, the conservative governor increases the frequency in 5% increments of the maximum frequency (this increment can be adjusted via the freq_step parameter). It also has its own thresholds, like down_threshold, which determine what CPU usage percentage triggers a downshift in speed. Essentially, conservative mode tries to only use as much CPU speed as needed, ramping up slowly and avoiding overshooting to max unless the load stays high. This is often recommended for battery-powered environments where ondemand’s instant jumps might be considered “too eager,” or in scenarios where a smoother power draw is desired (). The trade-off is that it may not respond as quickly to sudden heavy load – there could be a slight delay as it climbs through intermediate frequencies, which might impact performance for bursty workloads. In practice, the conservative governor can save a bit more energy than ondemand for some workloads, but the difference is often minor; ondemand itself already tries to save energy when idle. Conservative is mostly useful if you want to further smooth out frequency changes and possibly extend battery life a little more at the expense of immediate performance surges.
  • schedutil - The schedutil (scheduler utility) governor is the newest major governor, introduced around Linux 4.7-4.8, and it aims to integrate CPU frequency control tightly with the scheduler. Unlike ondemand and conservative, which run as separate routines checking CPU load, schedutil leverages the Linux kernel’s scheduler itself to make decisions. It uses the scheduler’s own tracking of task load (the PELT – Per-Entity Load Tracking – metrics) to determine appropriate CPU frequency. In fact, schedutil’s logic runs in scheduler context (in the scheduler code path) for efficiency. What this means is that whenever the scheduler is deciding what task to run or sees changes in CPU utilization, it can also quickly adjust the CPU frequency accordingly, with minimal overhead. Schedutil will generally scale the CPU frequency proportionally to the recent CPU utilization. For example, if a core is 50% busy (according to scheduler’s accounting), schedutil might choose roughly 50% of max frequency (with some headroom factor) instead of jumping straight to max. However, it has special behavior for certain kinds of tasks: if a real-time or deadline-scheduled task is running, schedutil will ramp the CPU to maximum frequency immediately (since those tasks are latency-sensitive). It also implements an “I/O wait boost” – briefly boosting frequency if a task was idle waiting for I/O and has just become runnable, anticipating it might need a burst of CPU. The schedutil governor’s design goal is to make frequency scaling more in tune with actual task needs and to reduce the overhead/lag of separate governor threads. By using the scheduler’s data directly, it avoids the periodic sampling and extra context switches that ondemand/conservative perform. In principle, this means schedutil should respond faster and with lower overhead, and not get “out of sync” with what the CPU is doing. Indeed, the kernel documentation notes that schedutil is meant as a replacement for the older ondemand and conservative governors, offering simpler and more efficient behavior. Today, many Linux distributions (Ubuntu included) have moved to use schedutil as the default governor on supported systems, because it tends to provide a good balance of performance and efficiency out-of-the-box. (Note: schedutil exposes only one tunable, rate_limit_us, which sets a minimum interval between frequency updates. This is to prevent it from changing frequency too rapidly in response to small load fluctuations).
  • userspace - In addition to the governors above, Linux also provides a userspace governor (and others like performance/powersave we covered). The userspace governor is not an automatic scaling algorithm at all – instead, it allows an external program or script to set the CPU frequency manually. When userspace is active, the kernel won’t try to choose frequencies; it simply exposes an interface (e.g. the file scaling_setspeed) for a user-level program (running as root) to request specific frequencies. This can be used by power management daemons or custom scripts if you want full manual control. In practice, most Ubuntu users won’t use userspace governor directly unless they have a very specific reason – it’s more common to use one of the automatic governors or tools like cpupower/TLP which behind-the-scenes might use userspace to set fixed frequencies. But it’s good to know it exists as an option for manual control or for specialized power daemons.

How Governors and Drivers Interact: It’s worth noting that the above governors operate on a generic layer, and underneath them are CPU frequency drivers (like acpi-cpufreq, intel_pstate, amd_pstate, etc.) that handle the actual hardware-level frequency changes. In principle, any governor can work with any driver, but some CPU drivers have their own internal governors or limitations. For example, Intel’s P-state driver and AMD’s CPPC driver are special cases – they implement their own algorithms and expose only limited “governor” choices. On Ubuntu (and Linux in general), this means the available governors and their behaviour might differ depending on your CPU:

  • Intel intel_pstate and AMD amd_pstate: These are modern scaling drivers for Intel and AMD CPUs that support hardware-controlled frequency scaling. If you have a relatively recent Intel CPU, Ubuntu will likely use intel_pstate by default instead of the older ACPI driver. In active mode (and with Intel HWP – Hardware P-states – enabled), the intel_pstate driver doesn’t use ondemand or schedutil; instead, it lets the CPU itself manage frequencies autonomously within a range. In this mode, you will only see two governors available: performance and powersave – but they don’t behave like the normal governors of those names. Instead, selecting performance or powersave with intel_pstate influences the processor’s internal policy (it sends an Energy Performance Preference (EPP) hint to the CPU). Essentially, both powersave and performance under intel_pstate will allow the CPU to scale frequencies dynamically on its own; the difference is that one biases toward conserving energy and the other biases toward higher performance. In fact, intel_pstate’s internal powersave algorithm is roughly analogous to schedutil (aiming for efficiency), and its performance algorithm keeps frequencies higher (similar to ondemand but with less concern for power). The result is that on Intel systems with P-state enabled, the default powersave governor still ramps up the CPU speed under load, just with a bias for power-saving (it might turbo a bit less aggressively or slow down more quickly when load drops). Conversely, switching to the performance governor on such systems tells the hardware to favour performance, potentially running at higher clocks more of the time. (The intel_pstate driver also has a passive mode where it can work with the generic governors, but by default Ubuntu uses active mode). AMD’s new amd_pstate driver (for Zen2+ CPUs) is similar – in active mode it relies on hardware CPPC mechanisms and offers powersave/performance as hints rather than literal fixed-frequency behavior. The key takeaway: if you only see powersave and performance as options on your Ubuntu system, you’re likely using the Intel/AMD P-state driver in hardware-controlled mode. Don’t be fooled by the name “powersave” here – your CPU will still scale up; it’s just using an internal policy favoring efficiency. (This is why some Ubuntu users notice the default governor is “powersave” on Intel – it’s intended to be the balanced choice for HWP).

intel_pstate powersave intel_pstate powersave governor with single-core load

intel_pstate performance intel_pstate performance governor with single-core load

  • ACPI cpufreq (traditional driver): On other systems, such as many AMD CPUs or older Intels (or if you disable intel_pstate), the kernel will use the classic ACPI acpi-cpufreq driver. With this driver, you’ll have the full range of governors (ondemand, conservative, schedutil, etc.) available, and their behavior is as described earlier. Ubuntu’s default in recent releases (20.04+, with modern kernels) is to use schedutil as the governor if it’s available. For example, Ubuntu Server 22.04 on an AMD Ryzen might default to schedutil (via acpi-cpufreq) for scaling. In older releases or certain configurations, ondemand was often the default. If schedutil isn’t available (say on a CPU where the driver doesn’t support it), the system might fall back to ondemand or even the intel_pstate internal scheme which appears as powersave. In any case, you can manually switch to any available governor if the default doesn’t suit your needs.

Checking and Setting the Current Governor on Ubuntu

Ubuntu does not expose a graphical setting for CPU governors by default (though some desktop environments and utilities might). However, it’s straightforward to check and change the governor using command-line tools or by interacting with sysfs.

  1. Checking the current governor and available governors: The current governor for each CPU core (or policy) is recorded in the file system under /sys/devices/system/cpu/. You can check it by reading, for example:

    1
    
     cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    

    output:

    1
    
     powersave
    

    This would output the governor name (e.g. powersave) for CPU0. Each CPU (or each policy group of CPUs) has its own scaling_governor file. A quicker way to see all cores’ governor at once is:

    1
    
     grep . /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
     /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu10/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu11/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu12/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu13/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu14/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu15/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu16/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu17/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu18/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu19/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu20/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu21/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu22/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu23/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu24/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu25/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu26/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu27/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu6/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu7/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu8/cpufreq/scaling_governor:powersave
     /sys/devices/system/cpu/cpu9/cpufreq/scaling_governor:powersave
    

    You can also see what governors are available on your system by checking scaling_available_governors:

    1
    
     cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
    
    1
    
     performance powersave
    

    The above might indicate that only two governors are compiled/available (common on an Intel P-state system). On another system, you might see ondemand conservative performance powersave schedutil userspace. This list depends on the CPU driver in use as discussed.

    A more user-friendly way is to use the cpupower utility. Ubuntu includes cpupower (as part of the linux-tools-common package), which provides a convenient interface to CPU frequency info. For example:

    • cpupower frequency-info – Gives a detailed report of the CPU driver, available frequencies, current frequency, and current governor for the CPUs. It will also list the available governors. Look for lines like “current policy: frequency should be within X and Y… The governor “powersave” may decide which speed to use within this range.”
    1
    
     cpupower frequency-info
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
     analyzing CPU 25:
       driver: intel_pstate
       CPUs which run at the same hardware frequency: 25
       CPUs which need to have their frequency coordinated by software: 25
       maximum transition latency:  Cannot determine or is not supported.
       hardware limits: 800 MHz - 4.30 GHz
       available cpufreq governors: performance powersave
       current policy: frequency should be within 800 MHz and 4.30 GHz.
                       The governor "powersave" may decide which speed to use
                       within this range.
       current CPU frequency: Unable to call hardware
       current CPU frequency: 800 MHz (asserted by call to kernel)
       boost state support:
         Supported: yes
         Active: yes
    
    • cpupower frequency-info -p – Shows the current scaling driver and governor for each policy.
    • cpupower monitor – Can live-monitor frequency and C-state usage, which is useful to see the governor in action (this is more advanced).
    1
    
     sudo cpupower monitor
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
     intel-rapl/intel-rapl:0
     0
     intel-rapl/intel-rapl:0/intel-rapl:0:0
     0
     intel-rapl/intel-rapl:0/intel-rapl:0:1
     0
         | Nehalem                   || Mperf              || RAPL               || Idle_Stats
      CPU| C3   | C6   | PC3  | PC6   || C0   | Cx   | Freq  || pack | core | unco  || POLL | C1_A | C2_A
        0|  0.00| 95.06|  0.00|  0.00||  0.73| 99.27|   921||2577935|1096128|     0||  0.00|  0.05| 99.27
        1|  0.00| 95.06|  0.00|  0.00||  0.05| 99.95|   934||2577935|1096128|     0||  0.00|  0.00| 99.75
        2|  0.00| 97.64|  0.00|  0.00||  0.87| 99.13|   983||2577935|1096128|     0||  0.00|  0.02| 99.09
        3|  0.00| 97.64|  0.00|  0.00||  0.01| 99.99|   899||2577935|1096128|     0||  0.00|  0.00| 99.94
        4|  0.00| 96.58|  0.00|  0.00||  1.50| 98.50|   997||2577935|1096128|     0||  0.01|  0.23| 98.09
        5|  0.00| 96.58|  0.00|  0.00||  0.01| 99.99|  1117||2577935|1096128|     0||  0.00|  0.00| 99.94
        6|  0.00| 99.08|  0.00|  0.00||  0.72| 99.28|   941||2577935|1096128|     0||  0.01|  0.57| 98.83
        7|  0.00| 99.08|  0.00|  0.00||  0.01| 99.99|  1194||2577935|1096128|     0||  0.00|  0.00| 99.92
        8|  0.00| 97.67|  0.00|  0.00||  1.56| 98.44|  1003||2577935|1096128|     0||  0.00|  0.05| 98.38
        9|  0.00| 97.67|  0.00|  0.00||  0.63| 99.37|  1028||2577935|1096128|     0||  0.00|  0.03| 99.28
       10|  0.00| 94.53|  0.00|  0.00||  1.34| 98.66|   999||2577935|1096128|     0||  0.00|  0.30| 98.30
       11|  0.00| 94.53|  0.00|  0.00||  0.01| 99.99|  1038||2577935|1096128|     0||  0.00|  0.00| 99.91
       12|  0.00| 94.03|  0.00|  0.00||  1.80| 98.20|   978||2577935|1096128|     0||  0.00|  0.36| 97.68
       13|  0.00| 94.03|  0.00|  0.00||  0.01| 99.99|   878||2577935|1096128|     0||  0.00|  0.00| 99.91
       14|  0.00| 95.29|  0.00|  0.00||  1.04| 98.96|   974||2577935|1096128|     0||  0.00|  0.11| 98.86
       15|  0.00| 95.29|  0.00|  0.00||  0.01| 99.99|   853||2577935|1096128|     0||  0.00|  0.00| 99.94
       16|  0.00| 97.34|  0.00|  0.00||  0.71| 99.29|   801||2577935|1096128|     0||  0.00|  0.02| 99.25
       17|  0.00| 99.92|  0.00|  0.00||  0.09| 99.91|   799||2577935|1096128|     0||  0.00|  0.00| 99.87
       18|  0.00| 100.0|  0.00|  0.00||  0.02| 99.98|   777||2577935|1096128|     0||  0.00|  0.00| 99.95
       19|  0.00|100.00|  0.00|  0.00||  0.01| 99.99|   797||2577935|1096128|     0||  0.00|  0.00| 99.95
       20|  0.00| 96.17|  0.00|  0.00||  0.13| 99.87|   789||2577935|1096128|     0||  0.00|  0.00| 99.74
       21|  0.00| 100.0|  0.00|  0.00||  0.02| 99.98|   793||2577935|1096128|     0||  0.00|  0.00| 99.96
       22|  0.00| 100.0|  0.00|  0.00||  0.01| 99.99|   795||2577935|1096128|     0||  0.00|  0.00| 99.96
       23|  0.00| 97.14|  0.00|  0.00||  0.35| 99.65|   798||2577935|1096128|     0||  0.00|  0.00| 99.63
       24|  0.00| 98.66|  0.00|  0.00||  0.83| 99.17|   800||2577935|1096128|     0||  0.00|  0.02| 99.10
       25|  0.00| 99.78|  0.00|  0.00||  0.20| 99.80|   799||2577935|1096128|     0||  0.00|  0.00| 99.78
       26|  0.00| 99.90|  0.00|  0.00||  0.05| 99.95|   794||2577935|1096128|     0||  0.00|  0.00| 99.92
       27|  0.00| 96.18|  0.00|  0.00||  0.21| 99.79|   800||2577935|1096128|     0||  0.00|  0.35| 99.41
    

    Similarly, the older cpufrequtils package provides cpufreq-info and cpufreq-set commands. For example, cpufreq-info will list each CPU core with its current frequency and governor, as well as the available options. It might output a summary like “CPU0… current governor: ondemand; available governors: performance, powersave, ondemand, conservative, schedutil”. Using these tools is often easier than dealing with raw sysfs files.

  2. Changing the governor (temporary): To change the governor, you have a few options. The simplest is using cpupower:

    1
    
     sudo cpupower frequency-set --governor performance
    

    This command will instruct the kernel to switch all CPUs (by default) to the performance governor. You can specify a particular core with -c <core_id> if you only want to change one CPU’s policy, but typically you want them all. When run, this takes effect immediately – you can verify by re-running cpupower frequency-info or checking the scaling_governor file again.

    Alternatively, you can directly write to the sysfs interface (this is essentially what these tools do under the hood). For example:

    1
    
     echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
    

    This will echo “performance” into each CPU’s scaling_governor file, effectively the same outcome. (It’s often recommended to use the provided tools or do this in a script, rather than manually every time).

    No matter the method, changing the governor on the fly does not persist after reboot by default. It will last until you reboot or change it again.

  3. Making the choice permanent (persistence): On Ubuntu, after a reboot, the system will usually revert to the default governor (often “powersave” on Intel or “schedutil”/“ondemand” on others, depending on version). To persist your preferred governor, you have a few approaches:

    • Use cpufrequtils config: If you install the cpufrequtils package, it provides a simple way to set a default governor at boot. Edit the file /etc/default/cpufrequtils (create it if it doesn’t exist) and add a line like: GOVERNOR=”performance”. You can also specify min/max frequencies there if desired. Once that is in place, enable the service with sudo systemctl enable cpufrequtils (or it may start automatically on reboot if installed). This ensures that at boot the cpufrequtils init script will set the specified governor for all CPUs. You can verify after reboot with cpufreq-info that the governor is as configured.
    • Disable Ubuntu’s automatic governor override: Ubuntu traditionally had an ondemand init script (now a systemd service) that, on boot, sets the governor to “ondemand” (or “powersave” on AC vs battery). In newer releases, this service might set schedutil or powersave by default. If you find your manual settings being overridden on boot, you can disable this by running: sudo systemctl disable ondemand and rebooting. This prevents Ubuntu from forcing a governor, so the system should stay with whatever you configure (which might be a BIOS default or the kernel default governor). After disabling that, you’d still need to set your desired governor some way (for example, via cpufrequtils as above, or a cron @reboot job, etc).
    • Using a systemd service or rc.local: You can create a custom systemd service that runs early in boot to set the governor. For instance, create a file /etc/systemd/system/setgovernor.service with appropriate [Service] lines to run the cpupower frequency-set -g command, then enable that service. Alternatively, if your system still has /etc/rc.local enabled, you could add the echo performance > /sys/devices/system/cpu/.../scaling_governor line there. Ensure it runs after cpufreq modules are loaded. This approach is a bit DIY, but effective if you prefer not to install extra packages.
    • TLP (for laptops): If you use TLP, the advanced power management tool commonly used on laptops, it can manage CPU governors automatically. In the TLP configuration (/etc/tlp.conf), you can set: CPU_SCALING_GOVERNOR_ON_AC=performance CPU_SCALING_GOVERNOR_ON_BAT=powersave (or any governors of your choice). When TLP starts (it runs at boot and on AC/battery events), it will apply these settings. For example, you might choose “performance” when on AC power and “ondemand” or “powersave” on battery. This is a convenient way to have the governor switch based on power source – many users want high performance when plugged in, but longer battery life when unplugged. By default, TLP might leave the governor alone unless configured; check TLP’s docs for the version you have. Note that TLP will override other settings when it kicks in, so use either TLP or your own scripts, but not both, to avoid confusion.
    • TuneD: For servers and advanced setups, TuneD (a daemon with various performance profiles) is available on Ubuntu. You can install tuned and activate profiles like throughput-performance (which among other things sets the CPU governor to performance) or powersave (sets powersave governor). TuneD profiles can encompass more than just CPU governor (they can tweak kernel parameters, disk settings, etc. for specific scenarios). For example, the “balanced” profile might use schedutil governor, while “powersave” uses powersave governor. Using TuneD can be overkill if you only care about the CPU freq governor, but it’s an option especially on servers where you might already be tuning various settings.

    After setting up persistence, always reboot to test that the governor sticks. You can run cpupower frequency-info or check /sys/devices/system/cpu/*/scaling_governor after reboot to ensure it’s in the desired mode.

  4. Verifying behavior: Once you’ve set a governor, you might want to verify that it’s doing what you expect. For instance, if you set powersave, you can check the CPU frequency doesn’t go above a low value even under load. If you set performance, you should see the CPU frequency at max (use watch cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq to see live frequency, or cpupower monitor). For dynamic governors like ondemand or schedutil, you can observe the frequency rising when you launch a CPU-intensive task and dropping when the task finishes. Tools like gnome-system-monitor or htop can also show current CPU frequencies per core to give you an idea of scaling in real time.

Tools and Utilities for CPU Frequency Management

We’ve already touched on several tools (cpupower, cpufrequtils, TLP, TuneD). Here’s a summary of useful utilities when exploring CPU scaling on Ubuntu:

  • cpupower: A command-line tool provided by Linux kernel tools (sometimes called cpupowerutils). Use this for querying and setting CPU frequency policies. Key commands: cpupower frequency-info (view info), cpupower frequency-set (set governor or frequency limits). This tool works both for traditional ACPI drivers and Intel pstate. It’s a convenient one-stop utility for most CPU power settings (it can also control CPU idle states, etc., but that’s beyond our scope).
  • cpufreq-utils (cpufreq-info, cpufreq-set): An older set of utilities that provide similar functionality. cpufreq-info gives detailed info per core/policy, including available frequencies and governors. cpufreq-set allows setting a governor or hard-setting a frequency (-f option) for a given core. Many how-tos use these, and they are simple to use. They require installing the cpufrequtils package on Ubuntu. This package also provides the /etc/default/cpufrequtils config for persistence as discussed.
  • Desktop applets or extensions: There are GUI tools that sit in your panel and let you switch governors or set frequencies. For example, indicator-cpufreq was a popular Ubuntu applet (especially in Unity days) that allowed choosing the governor from a menu. GNOME users on newer Ubuntu can use extensions like “CPU Power Manager” or “cpupower GNOME extension” which expose governor control. These are essentially front-ends to the same system settings. If you prefer not to touch the command line, these can be handy for quick changes (e.g., set performance mode before launching a game). Just be aware they also typically require appropriate privileges (they may need you to be in the right group or to have PolicyKit rules to allow changing CPU frequency).
  • TLP: As mentioned, TLP is primarily for laptops to automate power saving tweaks. It can manage governors, but also toggles Wi-Fi power saving, disk APUs, etc., based on AC or battery. It’s great for set-and-forget power management. If you install TLP on Ubuntu (it often comes pre-installed on some Ubuntu flavors or easily via apt), check /etc/tlp.conf for CPU scaling options. By default TLP might not force a governor unless you configure it – it often lets the kernel’s default (schedutil on ACPI systems, or powersave on Intel) rock on. But if you explicitly set the CPU_SCALING_GOVERNOR values, it will apply them.
  • TuneD: A profiling system that can switch multiple settings at once. For example, tuned-adm profile powersave will set a whole bunch of power-saving parameters (including likely the powersave governor). tuned-adm profile throughput-performance will do the opposite (set performance governor, enable turbo, etc.). This is more common in RHEL/CentOS world but is available on Ubuntu and can be useful on servers to quickly apply a known-good profile.
  • Monitoring tools: If you want to monitor frequencies and behavior, tools like watch -n1 “cpupower frequency-info” or watch -n1 grep "^[[:alpha:]]" /proc/cpuinfo can show frequency changes. There’s also i7z (for Intel) and turbostat which give deeper info on frequencies, C-states, and power draw. For a quick check of scaling, watch -n1 “cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq” (and similarly for other CPUs) is instructive: you’ll see the number rise to the max when you do something CPU-heavy.

In summary, Ubuntu’s default setup is usually fine for most users, but these tools give you the power (no pun intended) to tailor the CPU frequency policy to your needs – whether that’s squeezing out more battery life or cranking up performance.

Performance vs Power: Comparing Governors in Practice

How much difference do these governors actually make? The answer can depend on your workload and hardware. Here we’ll compare the governors on two main aspects: performance (speed/throughput) and power efficiency (energy usage/heat).

  • Raw Performance: The performance governor, by keeping the CPU at max frequency, generally ensures the lowest latency and highest throughput for CPU-bound tasks. There’s no waiting for the CPU to ramp up – it’s already at full speed. Governors like ondemand and schedutil, on the other hand, might introduce a slight delay when a sudden load appears (as they detect the load and then increase frequency). However, in modern implementations, this delay is very small (millisecond scale). In sustained heavy workloads (e.g., rendering a video, compiling a large program, or running scientific computations that keep the CPU at 100%), all governors that allow the CPU to reach max frequency will eventually deliver similar performance because the CPU will spend most of the time at max frequency regardless. In these cases, ondemand or schedutil will ramp up and the CPU will be at 100% frequency for the majority of the task, so the total time taken is nearly the same as performance governor. The differences come in how quickly they ramp and any overhead in doing so. Real-world benchmarks have shown that schedutil vs performance are often very close for sustained loads. For instance, in one broad test across over 200 benchmarks on an AMD system, the geometric mean performance with schedutil was only about 1% lower than with performance. This suggests that for most use cases, schedutil (the default on many systems) is nearly as good as locking at full speed. Ondemand is also generally very close to performance for heavy loads, since its algorithm jumps to max frequency as soon as the CPU is sufficiently utilized. That said, there are specific scenarios where the governor choice can have a noticeable impact:
    • Bursty or latency-sensitive workloads: If your workload consists of short bursts of work separated by idle periods, a dynamic governor might let the CPU drop to a low frequency between bursts and then needs to ramp up when a burst comes. The ramp-up isn’t instantaneous (though it’s fast). In some cases, the first few milliseconds of a burst might run at a lower frequency until the governor increases it. Usually this is negligible, but if the bursts are extremely short or your task is very latency-critical (e.g., high-frequency trading, audio processing), you might see a benefit to performance governor. For example, a database benchmark (MyRocks in one report) observed that using the performance governor yielded up to 2× higher throughput in a write-heavy test compared to schedutil. This was likely because schedutil wasn’t ramping up fast enough or staying at high frequency during the bursts of activity, whereas performance governor kept it ready at max. Such large differences are not common, but it illustrates that for some patterns, governor choice can matter a lot.
    • Conversely, if a governor like powersave is used, the CPU is locked at a low frequency and will certainly deliver lower performance on any non-trivial workload. The difference can be dramatic: CPU-intensive tasks may run significantly slower (proportionally to the frequency drop). In gaming benchmarks on Linux, for instance, using the powersave or conservative governors led to notably worse performance (lower frame rates) compared to ondemand or performance. This is expected because if you cap a 3.0 GHz CPU at 1.2 GHz, you roughly get that proportion of performance in CPU-bound sections of code. So, powersave and similar are only for when you accept a performance hit to save energy.
    • One other corner-case: very light background load. Sometimes a dynamic governor might oscillate the frequency or not go to max if it deems the load too low. conservative governor might hover at a medium frequency if the CPU usage never exceeds its up-threshold, whereas performance would still run at max regardless. But if the load is truly light, you likely don’t notice any performance issue (the CPU was mostly idle anyway).
  • Power Consumption and Heat: This is the flip side. Running the CPU faster uses more watts. However, modern CPUs and the Linux kernel also employ C-states (idle states) which cut power when the CPU is truly idle. There’s an interesting interaction: a CPU at high frequency but idle can enter deep C-states and actually not draw much power at all. On the other hand, a CPU at low frequency but 100% busy might draw more power (and definitely get more work done, albeit slower). Generally, though, if a CPU is doing the same amount of work, doing it at a higher frequency quickly and then going idle can be more efficient or at least comparable to doing it slowly over a longer time – this is often called “race to idle”. Governors like ondemand and schedutil embody that principle: get to higher speed when needed, then drop to low speed or idle. The performance governor will keep the CPU at max frequency even when idle, but the CPU can still drop into deep idle states if nothing is running. This means performance doesn’t necessarily mean full power draw 100% of the time; it just means when the CPU comes out of idle, it’ll be running fast. But on some systems, there is a cost: higher voltage and frequency might mean the CPU cannot enter the deepest C-states as often, or there is more background power leakage. In general, though, you can expect a machine locked to the performance governor to consume more power at idle than one on ondemand/schedutil, because the latter will often drop the frequency (and possibly voltage) to minimal when idle. The difference might be a few watts on a desktop. On a laptop, that could translate to a bit shorter battery life when you’re not actively using the CPU. Under load, performance governor obviously uses maximum power all the time. Ondemand or schedutil might, for certain workloads, decide to run at less than full frequency and thus save some energy while still meeting the demand. For example, if your CPU is 50% utilized, schedutil might keep it at 50% of max frequency (plus a little headroom) – running at a lower voltage/frequency is more power-efficient (it’s nonlinear: dropping freq/voltage can dramatically lower wattage). This can lead to cooler operation. A tangible example: A user on a forum noted that their CPU temperature under moderate use dropped from 75°C to 60°C by switching from the ondemand governor to the powersave governor. In that case, ondemand was frequently allowing higher speeds (and thus more heat) whereas powersave locked it low, reducing temperatures (with a performance penalty). Another data point: Using the performance governor might raise power usage on battery – one might see the system drawing several more watts, reducing battery runtime, compared to using a more conservative governor. In summary, power/thermal savings are significant with the conservative or powersave governors (at the cost of performance), whereas ondemand and schedutil aim to save power when possible without huge performance sacrifices. Schedutil is generally regarded as very efficient in terms of overhead and often chooses the “right” frequency to not waste power when full speed isn’t needed.
  • Responsiveness: Another aspect is how the system feels. A common observation is that the performance governor can make the system feel “snappier” because the CPU is always ready at high speed for any task (window rendering, app launch, etc.), whereas with ondemand/schedutil there might be a tiny lag while ramping up. On modern CPUs this lag is minimal (often on the order of 1-10 ms). Many users won’t notice a difference in interactive usage between schedutil and performance. However, certain interactive workloads (perhaps heavy multitasking or GUI animations) could benefit from performance mode if schedutil is being a bit slow to react. There is ongoing work to ensure schedutil (or the hardware’s own P-state logic) responds quickly enough to interactive needs – often it does, but if you ever find your laptop feeling sluggish under the default governor, switching to performance is a quick test to see if it improves responsiveness (at the cost of battery life). Conversely, on some systems, the default might already be performance (rare on Ubuntu nowadays, except perhaps on AC for certain tuned systems) and you might want to switch to schedutil to cool it down and still get almost the same performance in most situations.

Use-case recommendations:

  • For desktop users: Ubuntu Desktop typically will be using schedutil (or intel_pstate powersave, which as explained acts like schedutil). This is usually optimal for general use – it saves power when idle and gives performance when needed. You can trust the default in most cases. If you do gaming or audio production, etc., you might experiment with performance governor during those activities. Some gaming-oriented tools (like Feral’s Gamemode) will actually switch the CPU to performance governor while a game is running, then switch back to schedutil afterwards, to maximize game performance. This kind of dynamic switching can be the best of both worlds (there are tools and scripts to automate it).
  • For laptops on battery: You’d likely prefer schedutil or even conservative to stretch battery life. Powersave governor is an extreme option – it will definitely lengthen battery life but at a major speed cost (your CPU might be stuck at 0.8 GHz, making everything slower). A perhaps better approach than full powersave is to use schedutil and perhaps cap the max CPU frequency (you can echo a lower value to /sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq to prevent turbo boosts, for example). This can prevent the CPU from using the highest power states while still allowing some scaling. Tools like TLP allow setting a max frequency (% of turbo) on battery as well.
  • For servers: Servers that need consistent high performance (like a database server under load) often run the performance governor to avoid any latency in ramp-up. In fact, some server distributions default to performance governor for consistency. However, power costs and heat are considerations – in large deployments, schedutil or ondemand can save a lot of energy when the servers are not fully loaded. There’s a trade-off between absolute performance and efficiency. Some admins run performance during peak business hours and powersave overnight – this can be managed via cron or cluster management tools. Ubuntu Server’s default of schedutil is a reasonable middle ground for most, but it’s easy to pin to performance if you know you want maximum throughput. Always monitor CPU temperatures and cooling if you change to performance on a server; ensure the cooling system can handle it since the CPU may run hotter on average.

Benchmark Data: To illustrate differences, consider a few concrete points from available tests and reports:

A comprehensive benchmark on an AMD Ryzen system showed schedutil roughly on par with performance, with performance being ~1% faster on average over a large suite of tests (AMD Schedutil vs. Performance Governor Benchmarks On Linux …). This indicates the overhead of schedutil is very low and it chooses frequencies well for sustained loads. In specific tests like web serving or databases, one might see performance governor pull ahead by a larger margin. The MyRocks database example gave up to 2× the throughput with performance (Small Datum: Managing CPU frequency for AMD on Ubuntu 22.04), likely because schedutil didn’t ramp up fast enough during bursts. In another example, kernel developers noted that the intel_pstate “powersave” mode could be “lazy” in ramping, causing sluggishness, which is why some prefer forcing performance mode on Intel even for normal use ([SOLVED] Suggestion: use “performance” CPU frequency governor). Conversely, using the powersave governor has shown to significantly lower performance in CPU-bound tasks – one Phoronix test (on gaming) saw notable FPS drops in games under powersave (Ryzen 7 CPUFreq Governor Comparison For Linux Gaming On 4.12). Another user reported that using powersave made their system feel very sluggish, especially a high-end desktop where it cut the frequency to a fraction of its capability ([SOLVED] Suggestion: use “performance” CPU frequency governor). On the power side, a Slackware user measured that on a Haswell-E desktop, the intel_pstate powersave vs performance had interesting results: the system was sluggish on powersave and idle power consumption was actually higher than when using performance governor ([SOLVED] Suggestion: use “performance” CPU frequency governor). This was a surprising outcome and might be specific to how that CPU handles C-states, but it underscores that the relationship between frequency and power can be non-linear. Generally though, for most hardware, locking at a high frequency will increase power usage under light loads – your laptop might get warm doing nothing if stuck at 4 GHz. Schedutil/ondemand will drop it to, say, 1 GHz or lower when idle, letting the CPU (and fans) rest.

In Linux kernel development, schedutil is seen as the future because it aligns scheduling and frequency selection, reducing conflicts between “when to wake up the CPU” and “how fast to run it”. It’s simpler and has less CPU overhead monitoring the load. Over time, it has improved and many quirks have been worked out. But for most users, schedutil (or the intel_pstate default) provides a great balance.

To summarize the comparison:

  • If you need absolute maximum performance and consistent latency, use performance. Your CPU will stay at max clock. This is great for real-time audio processing, gaming, or heavy servers, but expect higher power draw and temperatures.
  • If you need maximum battery life or minimal heat, and don’t mind sacrificing speed, powersave will do that by capping at the lowest speed. But consider less drastic measures first (like schedutil plus limiting turbo) because powersave can be too slow for comfortable use.
  • For a balanced approach (dynamic scaling), ondemand and schedutil are the go-to. Ondemand has been tried-and-true for years with tunable aggressiveness, while schedutil is newer and integrates with CPU scheduler for smarter decisions. Both will run fast when you need it and slow when you don’t, saving energy in idle times. Schedutil tends to be the default now due to its design advantages.
  • conservative is a niche option if you found ondemand too jumpy; it will make your frequency changes smoother and possibly save a tiny bit more energy at the cost of some responsiveness. It’s arguably less relevant now that schedutil exists, but it’s there if you want that style of behavior.
  • userspace is for when you have your own logic (via a daemon or script) to set frequencies or governors.

Finally, keep in mind that CPU frequency is just one part of the performance/power puzzle. Modern CPUs also have turbo boost, idle states, multi-core considerations, and more. Frequency scaling governors decide base frequency behavior, but technologies like Intel Turbo Boost or AMD Precision Boost can temporarily push frequencies above the nominal max when thermal headroom allows – these work in tandem with the governor. For example, even with schedutil or ondemand, if your CPU sees a single-thread load, it might boost that one core to higher than base clock. Governors respect the limits (they won’t stop turbo unless you disable it), they just set the target within the allowed range. Also, extremely frequent changes in frequency can have minor performance costs (e.g., if voltage changes too often), but governors have tuning parameters (like the sampling_down_factor in ondemand, or rate_limit_us in schedutil) to avoid jitter.

In summary, Linux CPU governors give you control over the performance-vs-power tradeoff. Ubuntu’s defaults (schedutil or intel_pstate’s powersave mode) are generally well-chosen for typical workloads, offering power efficiency without unduly compromising performance. But for those who want to delve deeper, understanding these governors lets you tweak your system: you can squeeze out extra battery life when needed or unlock full performance at the cost of more energy. With tools like cpupower and TLP, experimentation is easy. The best choice of governor ultimately depends on your specific needs – and you can always change it on the fly, which is the beauty of Linux’s dynamic frequency scaling.

This post is licensed under CC BY 4.0 by the author.