How to make your (ThinkPad) laptop run longer, faster, and preserve your battery health.
There used to be a time when Linux on the laptop meant putting up with cooling fans whirring away at full speed, while your machine was sucking its battery empty in record time. If you wanted proper support for all the fancy advanced power management that mobile processors had to offer, you were stuck with Windows.
Those days have been over for a while now though, particularly when you own a reasonably well supported machine. In which case Linux can and will actually outperform Windows quite noticeably in terms of battery endurance, and sustained compute performance when plugged into AC power.
Please read our disclaimer carefully before considering to proceed with this guide.
Most of the suggestions we provide should work with other current generation Intel laptops, but some are ThinkPad specific. We shall try to point that out where applicable. This guide assumes you are running a recent version of Ubuntu, either 18.04 or 20.04 desktop, on your machine, but then again, most things can be made to work with other distributions too. We shall split this one into two sections:
1) Making your ThinkPad run longer and preserving battery health:
TLP combines the manipulation of all modern power management functions of laptop hardware into one application and config file. It significantly improves run time. Particularly if you are willing to de-tune your system and under clock it while running on battery. Given the performance reserves most modern CPUs have this is entirely reasonable for normal office and web browsing workloads.
On most ThinkPad laptops TLP will also allow you to set battery charge thresholds. Under Windows the Lenovo Vantage tool provides similar functionality. What's the benefit of not charging the battery to full capacity every time? Charging only to e.g. 85% and then stopping the charging process, even if the machine remains plugged into AC power, significantly prolongs the useful life of a battery pack, particular on machines that spend most their life as desktop replacements plugged into a charger 24/7. Electric vehicles use the same technique to prolong the service life of their battery packs. You can always temporarily raise or remove the charge threshold and charge to 100% if you need every last mWh of power for that extra long flight or road trip.
Setting it up, use the project PPA to get the most recent version:
sudo add-apt-repository ppa:linrunner/tlpsudo apt-get update
Install the following packages:
- tlp (PPA or universe) – Power saving
- tlp-rdw (PPA or universe) – optional, Radio Device Wizard
The above works for most laptops, the following is ThinkPad specific and enables some valuable extra functionality. Quoting from the project website:
"Depending on your model and kernel version external kernel module(s) are required to provide battery charge thresholds and recalibration.
The output of tlp-stat -b (version 1.2.2 or higher recommended) will guide you which package to install:
- acpi-call-dkms (universe) – optional – External kernel module providing battery charge thresholds and recalibration for newer ThinkPads (X220/T420 and later)
- tp-smapi-dkms (PPA or universe) – optional – External kernel module providing battery charge thresholds, recalibration and specific tlp-stat -b output for older ThinkPads
Install them either with your favorite package manager or the command:"
sudo apt-get install tlp tlp-rdw# ThinkPads require an additional:sudo apt install acpi-call-dkms tp-smapi-dkms# on (much) older kernels like 3.4 you'll also need this:sudo vi /etc/pm/sleep.d/thinkpad_acpiSUSPEND_MODULES="thinkpad_acpi"
The project website also provides further guidance on the correct kernel module for specific machines as well as how to deal with DKMS on machines with secure boot enabled.
I am including the TLP config file for my daily driver below. With average workloads this one gets me several hours of extra battery life. As you can see this config throttles back the CPU quite aggressively when running on battery.
TLP_ENABLE=1TLP_DEFAULT_MODE=BATTLP_PERSISTENT_DEFAULT=0DISK_IDLE_SECS_ON_AC=0DISK_IDLE_SECS_ON_BAT=5MAX_LOST_WORK_SECS_ON_AC=15MAX_LOST_WORK_SECS_ON_BAT=60CPU_HWP_ON_AC=balance_performanceCPU_HWP_ON_BAT=powerCPU_MIN_PERF_ON_AC=15CPU_MAX_PERF_ON_AC=100CPU_MIN_PERF_ON_BAT=5CPU_MAX_PERF_ON_BAT=50CPU_BOOST_ON_AC=1CPU_BOOST_ON_BAT=0SCHED_POWERSAVE_ON_AC=0SCHED_POWERSAVE_ON_BAT=1NMI_WATCHDOG=0ENERGY_PERF_POLICY_ON_AC=performanceENERGY_PERF_POLICY_ON_BAT=powerDISK_DEVICES="nvme0n1 sda"DISK_APM_LEVEL_ON_AC="254 254"DISK_APM_LEVEL_ON_BAT="128 128"SATA_LINKPWR_ON_AC="med_power_with_dipm max_performance"SATA_LINKPWR_ON_BAT="med_power_with_dipm min_power"AHCI_RUNTIME_PM_TIMEOUT=15PCIE_ASPM_ON_AC=performancePCIE_ASPM_ON_BAT=powersaveINTEL_GPU_MIN_FREQ_ON_AC=300INTEL_GPU_MIN_FREQ_ON_BAT=300INTEL_GPU_MAX_FREQ_ON_AC=1000INTEL_GPU_MAX_FREQ_ON_BAT=600INTEL_GPU_BOOST_FREQ_ON_AC=1000INTEL_GPU_BOOST_FREQ_ON_BAT=700RADEON_POWER_PROFILE_ON_AC=defaultRADEON_POWER_PROFILE_ON_BAT=defaultRADEON_DPM_STATE_ON_AC=performanceRADEON_DPM_STATE_ON_BAT=batteryRADEON_DPM_PERF_LEVEL_ON_AC=autoRADEON_DPM_PERF_LEVEL_ON_BAT=autoWIFI_PWR_ON_AC=offWIFI_PWR_ON_BAT=onWOL_DISABLE=YSOUND_POWER_SAVE_ON_AC=0SOUND_POWER_SAVE_ON_BAT=1SOUND_POWER_SAVE_CONTROLLER=YBAY_POWEROFF_ON_AC=0BAY_POWEROFF_ON_BAT=0BAY_DEVICE="sr0"RUNTIME_PM_ON_AC=onRUNTIME_PM_ON_BAT=autoUSB_AUTOSUSPEND=1USB_BLACKLIST_BTUSB=0USB_BLACKLIST_PHONE=0USB_BLACKLIST_PRINTER=1USB_BLACKLIST_WWAN=0RESTORE_DEVICE_STATE_ON_STARTUP=1START_CHARGE_THRESH_BAT0=85STOP_CHARGE_THRESH_BAT0=90START_CHARGE_THRESH_BAT1=85STOP_CHARGE_THRESH_BAT1=90RESTORE_THRESHOLDS_ON_BAT=1NATACPI_ENABLE=1TPACPI_ENABLE=1TPSMAPI_ENABLE=1
Note, this machine has two batteries, which is reflected in the config.
2) Making your ThinkPad run faster:
While most people think of raising the core voltage for over-clocking and big elaborate cooling systems when trying to increase the speed of their CPU, Intel laptop CPUs actually offer another approach. Provided you have a CPU generation later than Haswell you should be able to apply a fixed voltage offset to the different voltage planes and thereby undervolt the CPU.
The undervolt tool by georgewhewell is one of the most convenient ways of achieving this under Linux. His github repo below provides excellent instructions on how to install and configure the undervolt tool, so I won't repeat them here and just provide the link:
https://github.com/georgewhewell/undervolt
While this might seem at first counter intuitive for achieving performance gains, this works based on the fact that most dies sold to OEMs are of a sufficiently high quality that they will still run stably with their core voltage dropped between 75 and 100 mV. The offset you can achieve depends on your individual CPU. Some samples are can tolerate a little more others less.
Undervolting the CPU's voltage planes results in less heat under load, which in turn avoids the automatic thermal throttle kicking in when running with automatically boosted clock speeds under Intel turbo boost. Most laptop CPUs are only able to sustain turbo boost frequencies for a minute or two before their cooling systems get overwhelmed and they throttle back. A high quality CPU sample undervolted in the same machine can sustain turbo boot for hours at a time. Thus your machine essentially runs natively overclocked while producing less heat under normal operation, leading to quieter fans.
Once you have mastered the instructions form the readme of the undervolt repo, you need to find the right settings that work for your specific machine.
So you need to test your machine under full load until it crashes, then reduce the offset by e.g. 5 mV and test again until you achieve a stable system that will run without crashing. Ideally you should let it run under load for an hour or more.
To test stability, try system stability tester. Get the latest generic built from: http://systester.sourceforge.net
Yes, this 8 year old code but still does the job just fine.
tar zxvf systester-1.5.0-linux-amd64.tar.gzcd systester-1.5.0-linux-amd64sudo cp systester /usr/local/bin
Make executable if needed.
To run the application, you can simply run this command:
systester
That's it!