Fix laptop battery drain

Excessive battery drain on a Fedora laptop is usually caused by high CPU wake-ups, a power-hungry kernel driver, or a missing power management profile, all of which can be diagnosed and fixed with standard Fedora tools.

You close the lid and the battery dies

You close your laptop lid for a quick coffee run. You expect four hours of work. When you return, the battery indicator is blinking red and the system is shutting down. You check the settings. Everything looks normal. The drain is real, but the cause is hidden in kernel parameters, background daemons, or a misconfigured driver. This article walks you through diagnosing the leak and plugging it.

How Linux manages power

Linux power management is a negotiation between the kernel, the hardware, and the userspace daemons. The kernel tries to put devices to sleep when idle. Hardware interrupts wake them up. If a driver sends too many interrupts, or a process keeps a core busy, the system stays in a high-power state. Think of it like a car idling in gear. The engine is running, but the car isn't moving. The fuel burns anyway. Your job is to find what is keeping the engine revved and shift it into neutral.

The kernel exposes knobs for CPU frequency, disk spin-down, and radio polling. Userspace tools read sensor data and adjust those knobs. Fedora ships with a default daemon that handles this for most desktop users. Advanced users often replace it with a more granular tool. The tools conflict if you run them together. Pick one strategy and stick to it.

Diagnose with powertop

powertop is the diagnostic standard for power consumption. It measures average power draw and identifies which kernel subsystems are preventing idle states. It also provides a list of "tunables" that are currently set to a power-inefficient value.

Install the tool and run it in interactive mode. The interface updates in real time.

sudo dnf install powertop
# Install powertop from the default repositories
sudo powertop
# Run in interactive mode to see live metrics

Navigate to the Tunables tab using the arrow keys. Look for items marked Bad. A "Bad" tunable means the kernel has a configuration option that saves power, but the current setting wastes it. Press Enter on each item to toggle it to Good. This applies the fix for the current session only.

To make the fixes permanent, use the auto-tune feature. This generates a systemd service that applies the good tunables on boot.

sudo powertop --auto-tune
# Apply all Good tunables immediately
sudo systemctl enable powertop
# Enable the powertop service to persist tunables across reboots

Run powertop for five minutes before you trust the numbers. The first minute is noise. The average power line stabilizes after the system settles.

Choose a power management daemon

Fedora Workstation ships with power-profiles-daemon. It integrates with GNOME and KDE, exposing power modes in the desktop menu. It handles CPU frequency scaling and GPU power states based on the selected profile.

Check the current profile and switch modes using the command line.

powerprofilesctl list
# List available profiles and show the active one
powerprofilesctl set power-saver
# Switch to power-saver mode to reduce CPU frequency and background activity

The daemon reacts to lid closures and AC power changes automatically. You can force a mode change when you know a heavy workload is coming.

Some users prefer tlp for finer control. TLP manages USB autosuspend, CPU frequency scaling, and disk power management with a configuration file. It does not integrate with the desktop environment. It runs silently in the background.

Install TLP and enable the service. You must disable the default daemon first. Running both causes them to fight over the same kernel knobs. The result is constant toggling and higher power draw.

sudo systemctl disable power-profiles-daemon
# Stop the default daemon to prevent conflicts
sudo dnf install tlp tlp-rdw
# Install TLP and the radio device wizard for Wi-Fi/Bluetooth handling
sudo systemctl enable --now tlp
# Start TLP immediately and enable it for boot

Edit the configuration in /etc/tlp.conf. Never edit files in /usr/lib/. Those files ship with the package and get overwritten on updates. User modifications belong in /etc/.

Disable the default daemon before enabling TLP. Two drivers fighting for the same wheel causes vibration and drain.

Hunt runaway processes

A single process can consume enough CPU to drain the battery in hours. Background services sometimes enter a tight loop due to a bug or a missing dependency. systemd-cgtop shows resource usage by cgroup, which maps closely to services.

systemd-cgtop
# Display CPU and memory usage sorted by systemd cgroups

Look for services with high CPU usage that should be idle. If you find a culprit, check its status before stopping it. The status output includes recent log lines and the current state.

systemctl status <service-name>
# Show state, recent logs, and dependencies for the unit

If the service is stuck, restart it. If the problem persists, stop it and investigate the logs.

sudo systemctl restart <service-name>
# Restart the service to clear a transient stuck state

Kill the runaway process. A stuck loop in a background service burns power faster than the display.

Tune hardware interfaces

Some hardware components ignore global power profiles. Wi-Fi cards often keep the radio fully awake to minimize latency. SATA controllers may keep the link active even when the disk is idle. You can override these defaults manually.

Check the Wi-Fi power save state. The interface name varies by system. wlan0 is common but not guaranteed.

iw dev
# List all wireless interfaces and their current names
iw dev wlan0 get power_save
# Check if power save is enabled on the specific interface

If power save is off, enable it. This reduces the radio polling rate. Latency may increase slightly, which is acceptable for most desktop use.

sudo iw dev wlan0 set power_save on
# Enable power saving for the Wi-Fi interface to reduce radio activity

For SATA devices, the link power management policy controls how aggressively the controller puts the link to sleep. The default is often max_performance. Switching to med_power_with_dipm enables device-initiated power management.

echo med_power_with_dipm | sudo tee /sys/class/scsi_host/host*/link_power_management_policy
# Set link power management to medium power with device-initiated power management

Verify the interface name. wlan0 is a convention, not a guarantee.

Check battery health

Software tuning cannot fix a chemically degraded battery. If the battery capacity has dropped significantly, the percentage drops faster because the total energy is lower. upower reports the current charge and the design capacity.

upower -i $(upower -e | grep BAT)
# Query the battery device for detailed metrics

Look for energy-full and energy-full-design. energy-full is the maximum charge the battery can hold right now. energy-full-design is the capacity when the battery was new. Calculate the ratio. If energy-full is less than 80% of energy-full-design, the battery is degraded.

Replace the battery if the ratio drops below 80%. Software cannot restore chemistry.

Common pitfalls

Errors usually point to a configuration mismatch or a missing dependency. If iw reports Error: no such device, the interface name is wrong. Run ip link to find the actual name. The name might be wlp2s0 or wlx... depending on the kernel version and udev rules.

If you install TLP without disabling power-profiles-daemon, the system fights itself. One daemon turns power saving on, the other turns it off. The result is constant toggling and higher drain. Check which service is active.

systemctl is-active power-profiles-daemon tlp
# Check the active state of both daemons

If a tool refuses to run and you see permission errors, check SELinux. Fedora enforces SELinux by default. Denials appear in the journal with a one-line summary.

journalctl -t setroubleshoot
# View SELinux denial summaries with human-readable explanations

Check SELinux denials if a tool refuses to run. journalctl -t setroubleshoot shows the block.

Decision matrix

Use powertop --auto-tune when you want a quick, safe improvement without changing configuration files. Use power-profiles-daemon when you are running GNOME or KDE and want desktop integration. Use tlp when you need granular control over USB autosuspend or CPU frequency scaling on older hardware. Use iw dev set power_save on when your Wi-Fi card ignores the global power profile. Use upower when you suspect the battery is chemically degraded rather than misconfigured.

Where to go next