Setting TLP and walking away is a good start, but real power savings come from identifying and fixing the specific wakeup offenders on your particular hardware and workload. This chapter covers the tools for deep power profiling on Linux.
powertop is an interactive ncurses tool developed by Intel that estimates power consumption and identifies power management problems.
sudo powertop
Navigate tabs with Tab / Shift+Tab:
Overview: Estimated total power consumption and breakdown by component (CPU, disk, GPU, audio). This estimate is based on C-state residency, not a direct measurement.
Idle stats: CPU C-state residency percentages. Healthy idle looks like: C0 < 5%, C1/C2 < 10%, C7/C8/C10 > 80%. If the CPU cannot reach deep C-states (C7+), something is preventing it — usually a device or process that requested a CPU wake-up.
Wakeups: The critical tab for optimization. Lists every interrupt source ordered by wakeup frequency. Common offenders:
[kernel timer] — timer-based wakeups from kernel subsystemsiwlwifi — WiFi driver pollingsnd_hda_intel — audio device keeping the CPU awakeDevice stats: Power state of PCIe devices, USB devices, and SATA devices. Each should ideally show D3 (device suspended) when idle.
Tunables: A list of recommended settings. The Good/Bad status shows which settings are already applied.
For automated analysis, export to CSV:
sudo powertop --csv=powertop_report.csv --time=30
The CSV includes per-process wakeup data. Parse it to find the top wakeup offenders:
import csv, pathlib
def parse_wakeups(csv_path: str, top_n: int = 10):
rows = []
with open(csv_path) as f:
for line in f:
parts = line.strip().split(';')
if len(parts) >= 3 and parts[0].replace('.','',1).isdigit():
rows.append((float(parts[0]), parts[2].strip()))
rows.sort(reverse=True)
for rate, name in rows[:top_n]:
print(f"{rate:8.2f} wakeups/s {name}")
parse_wakeups("powertop_report.csv")
Full script with CSV section detection is in code/powertop_report_parser.py.
turbostat (part of linux-tools) reports per-CPU C-state residency, frequency, temperature, and power in a live table:
sudo turbostat --interval 5 --show Pkg_W,Core_W,CPU%c1,CPU%c6,CPU%c7,Avg_MHz
Key columns:
Pkg_W: Package power (from RAPL) — the most useful single numberCPU%c1, CPU%c6, CPU%c7: Time spent in each C-state (higher Cn = deeper sleep)Avg_MHz: Average effective frequencyIf CPU%c7 is low (< 50% at idle), something is preventing the deepest C-state. Run turbostat while progressively closing applications to identify the culprit.
s-tui is a terminal-based stress and monitoring tool that shows CPU frequency, utilization, and temperature in real time as a graph. Install with pip install s-tui.
s-tui
Use it to verify that:
no_turbo=1)Audio device (snd_hda_intel): HDA audio controllers are notorious for preventing PC6/PC7 C-states. Fix: enable audio codec power management.
echo 1 | sudo tee /sys/module/snd_hda_intel/parameters/power_save
echo Y | sudo tee /sys/module/snd_hda_intel/parameters/power_save_controller
TLP applies this automatically when SOUND_POWER_SAVE_ON_BAT=1 is set in /etc/tlp.conf.
USB devices: A USB device that does not support autosuspend will prevent the USB controller from suspending, costing 0.5–1 W. Identify the device, check if it causes issues with autosuspend enabled, and add its ID to TLP’s USB_ALLOWLIST if needed.
Timer-heavy applications: Some applications poll APIs, network sockets, or files at high frequency. Use perf top to identify which applications are consuming the most CPU time even at low utilization — they may be spinning in a polling loop.
sudo perf top --sort comm,symbol
Kernel modules: Some drivers do not support runtime power management properly. Check dmesg | grep "power management" and kernel module parameters for power_save options.
After profiling, document your baseline and target:
| State | Before Optimization | After Optimization |
|---|---|---|
| Screen off, idle | 8.5 W | 4.2 W |
| Screen on, idle | 12.0 W | 7.5 W |
| Light work (editing) | 15.0 W | 11.0 W |
| Battery life (estimate) | 4.5 hours | 8+ hours |
Use upower -d to read the current energy rate in watts:
upower -d | grep -E "energy-rate|state"
Measure over several minutes at a consistent workload — the value fluctuates with CPU activity.
| ← Chapter 8: Laptop Display, Suspend, and Wakeup | Table of Contents | Chapter 10: NUC and Small Server BIOS and Idle Tuning → |