Modern CPUs change their frequency and voltage many times per second to save power when idle and reach full speed under load. The kernel's frequency driver and governor decide how fast that happens, which affects latency, throughput and power draw. In this tutorial you will identify the frequency driver on an Ubuntu 24.04 server, choose a governor and energy preference, control turbo boost and idle states with cpupower, and make the configuration persistent with a systemd unit.

Prerequisites

  • A dedicated or bare metal server running Ubuntu 24.04 LTS with an Intel or AMD CPU.
  • A non-root user with sudo privileges.
  • Access to the server's BIOS/UEFI settings, or at least knowledge of its power profile, since the firmware can override what the OS requests.

Step 1 - Installing cpupower

cpupower reads and changes frequency and idle settings for all CPUs at once. On Ubuntu it ships in the linux-tools packages that match the running kernel:

sudo apt update
sudo apt install linux-tools-common linux-tools-$(uname -r)

Verify it works:

cpupower --version

If you later upgrade the kernel, install the matching linux-tools package again, or install the linux-tools-generic metapackage so it follows the generic kernel automatically.

Step 2 - Identifying the driver and governor

Show the current frequency configuration of CPU 0:

cpupower frequency-info
analyzing CPU 0:
  driver: intel_pstate
  CPUs which run at the same hardware frequency: 0
  hardware limits: 800 MHz - 4.70 GHz
  available cpufreq governors: performance powersave
  current policy: frequency should be within 800 MHz and 4.70 GHz.
                  The governor "powersave" may decide which speed to use
                  within this range.
  current CPU frequency: 1.20 GHz (asserted by call to kernel)
  boost state support:
    Supported: yes
    Active: yes

The driver determines which options you have:

DriverCPUsGovernorsNotes
intel_pstateIntel Sandy Bridge and newerperformance, powersaveIn active mode it does its own scaling. powersave is dynamic, not a fixed low frequency
amd-pstate-eppAMD Zen 2 and newer with CPPCperformance, powersaveSame model as intel_pstate, uses an energy preference hint
amd-pstateAMD Zen 2 and newerschedutil, ondemand, performance, ...Passive mode, the kernel governor picks frequencies
acpi-cpufreqOlder CPUs, or when the above are disabledschedutil, ondemand, conservative, performance, powersave, userspaceUses ACPI P-states defined by the firmware

You can also read the driver and governor directly from sysfs:

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

To see the real-time frequency of every core, run:

watch -n 1 "grep MHz /proc/cpuinfo"

Step 3 - Choosing a governor

The governor is the policy that turns CPU load into a frequency. For servers the choice is usually between two:

  • performance: keeps the CPU at the highest frequency the driver allows. Lowest latency and most consistent response times, at the cost of higher idle power. Good for databases, trading, game servers and anything latency-sensitive.
  • powersave (with intel_pstate or amd-pstate-epp) or schedutil (with acpi-cpufreq or passive amd-pstate): scales frequency with load. Uses much less power when idle and still reaches full speed under sustained load, but each burst takes a few milliseconds to ramp up. Good for web servers, build machines and general workloads.

Set the governor on all CPUs:

sudo cpupower frequency-set -g performance
Setting cpu: 0
Setting cpu: 1
...

Verify that every CPU now uses it:

cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor | sort | uniq -c
     16 performance

Step 4 - Setting the energy performance preference

With intel_pstate and amd-pstate-epp, the hardware makes the final frequency decision based on an Energy Performance Preference (EPP) hint. It is often the best knob to tune, because it keeps dynamic scaling while shifting the balance toward speed or efficiency.

List the accepted values:

cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences
default performance balance_performance balance_power power

Read the current one and set balance_performance on all CPUs, a good choice for most servers running the powersave governor:

cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
echo balance_performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference

Step 5 - Controlling turbo boost

Turbo boost lets some cores run above the base frequency while there is thermal and power headroom. It increases peak performance but also makes timing less predictable, which matters for benchmarks and some latency-critical workloads.

The control file depends on the driver.

With intel_pstate, 1 means turbo is disabled:

cat /sys/devices/system/cpu/intel_pstate/no_turbo
echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo

With acpi-cpufreq (and amd-pstate on kernels that provide it), a global boost file exists instead, where 1 means boost is enabled:

cat /sys/devices/system/cpu/cpufreq/boost
echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost

Confirm the change in the boost state support section of cpupower frequency-info. Most production servers should keep turbo enabled. Disable it for reproducible benchmarks, or when the CPU hits thermal or power limits and throttles unevenly.

Step 6 - Limiting deep idle states (C-states)

When a core has nothing to do, it enters an idle state (C-state). Deeper states save more power but take longer to wake up, from a few microseconds up to hundreds. For most servers this is irrelevant, but for very latency-sensitive network or trading workloads the wake-up time can show up in tail latency.

List the idle states and their exit latency:

cpupower idle-info
CPUidle driver: intel_idle
CPUidle governor: menu
analyzing CPU 0:

Number of idle states: 4
Available idle states: POLL C1 C1E C6
C1:
Flags/Description: MWAIT 0x00
Latency: 2
...
C6:
Flags/Description: MWAIT 0x20
Latency: 170

Disable every idle state with an exit latency above 10 microseconds, which keeps the shallow ones and blocks the deep ones:

sudo cpupower idle-set -D 10

Re-enable all of them with:

sudo cpupower idle-set -E

This increases idle power consumption noticeably and can reduce turbo headroom on some CPUs, so only apply it after measuring a real latency improvement.

Step 7 - Making the settings persistent

Sysfs changes are lost at reboot. A small systemd oneshot unit reapplies them on every boot. Create it:

sudo nano /etc/systemd/system/cpu-tuning.service

Add the following, keeping only the lines you actually want:

[Unit]
Description=Apply CPU frequency and idle settings
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/usr/bin/cpupower frequency-set -g performance
# ExecStart=/usr/bin/cpupower idle-set -D 10
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Before relying on it, check that the path exists on your system with command -v cpupower. Enable and start the unit:

sudo systemctl daemon-reload
sudo systemctl enable --now cpu-tuning.service

Verify that it ran successfully:

systemctl status cpu-tuning.service
● cpu-tuning.service - Apply CPU frequency and idle settings
     Loaded: loaded (/etc/systemd/system/cpu-tuning.service; enabled; preset: enabled)
     Active: active (exited) since Thu 2026-09-24 10:02:13 UTC; 3s ago

Reboot once and repeat the check from Step 3 to confirm the governor survives the restart.

Step 8 - Monitoring real frequency and power

turbostat, included in the same linux-tools package, reports the actual average frequency, time spent in each C-state and, on supported CPUs, package power in watts:

sudo turbostat --quiet --show Busy%,Bzy_MHz,PkgWatt --interval 5
Busy%   Bzy_MHz PkgWatt
3.12    3890    41.27

Bzy_MHz is the average frequency while cores were busy, which is more meaningful than the instantaneous values in /proc/cpuinfo. Compare these numbers before and after each change, together with your application's own latency metrics.

Troubleshooting

  • /sys/devices/system/cpu/cpu0/cpufreq does not exist: the server is a virtual machine, or frequency control is disabled in the BIOS. On bare metal, check the BIOS power profile and set it to "OS Control" or similar.
  • The frequency stays low under load with performance: the firmware or BMC may be capping power, or the CPU is thermally throttling. Check turbostat for low PkgWatt with high Busy% and review BIOS power limits and cooling.
  • cpupower: command not found after a kernel upgrade: install linux-tools-$(uname -r) for the new kernel.

Conclusion

You identified your CPU frequency driver, selected a governor and energy preference that fit the workload, controlled turbo boost and deep idle states, and made the settings persistent across reboots. For most servers, powersave with balance_performance is an efficient default, while performance suits latency-critical systems. As next steps, benchmark your application before and after each change, and review memory and I/O scheduler tuning to remove other bottlenecks.