Skip to content
HackHourHQ

HH-0014 · Rev A ·

Cap a laptop battery at 80% on Linux (ThinkPad, sysfs, survives reboot)

Kip CroninPublished ~4 min read

On a ThinkPad, write the limit to sysfs: echo 80 | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold stops charging at 80%. A one-line systemd service re-applies it at every boot. Our laptop server has run this way since May 2026, and its battery history shows charging stop at exactly 80.

We did this for a laptop that's plugged in all the time as a server, in the always-on Ubuntu laptop checklist. It's just as useful on a laptop that lives on a desk.

Check your laptop supports it

ls /sys/class/power_supply/
grep -H . /sys/class/power_supply/BAT0/charge_control_start_threshold \
          /sys/class/power_supply/BAT0/charge_control_end_threshold
/sys/class/power_supply/BAT0/charge_control_start_threshold:0
/sys/class/power_supply/BAT0/charge_control_end_threshold:80

On ThinkPads the files come from the thinkpad_acpi driver. The kernel docs say the start value takes 0 to 99 and the end value 1 to 100, and that the files only exist "for those batteries that are supported by the driver". The names are a standard kernel interface (sysfs-class-power), so some other laptops' drivers provide them too. If the files aren't there, your driver doesn't offer this and the hack won't work on that machine. Check your battery's name too: it's BAT0 on our X1 Carbon, but some laptops have BAT1 or two batteries.

Set it now

echo 80 | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold

The end threshold is "a battery percentage level, above which charging will stop". The sysfs ABI adds that drivers may round the value, and "reading back the value will show the actual threshold set by the driver", so read it back after writing.

Keep it after a reboot

The kernel docs don't say whether the value survives a reboot, so ours is set by a oneshot service at every boot:

# /etc/systemd/system/battery-charge-cap.service
[Unit]
Description=Cap BAT0 charge at 80%
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo 80 > /sys/class/power_supply/BAT0/charge_control_end_threshold'

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable battery-charge-cap.service

On the last boot it ran like this:

2026-10-14T14:53:22+03:00 x1 systemd[1]: Starting battery-charge-cap.service - Cap BAT0 charge at 80%...
2026-10-14T14:53:22+03:00 x1 systemd[1]: battery-charge-cap.service: Deactivated successfully.
2026-10-14T14:53:22+03:00 x1 systemd[1]: Finished battery-charge-cap.service - Cap BAT0 charge at 80%.

Does the value survive a cold boot on its own? On our machine we can't tell. The service runs within the first minute of every boot, and nothing logs the threshold before it does. If you want to know for your laptop, disable the service, set a value, power off, boot, and read the file before anything else writes it.

Proof it stops at 80

UPower keeps a charge history in /var/lib/upower/. On 8 October our laptop started up with the battery nearly empty, charged on AC, and stopped at 80:

awk '{print strftime("%Y-%m-%dT%H:%M:%S",$1), $2, $3}' /var/lib/upower/history-charge-02DL004-51-1550.dat
2026-10-08T21:48:42 4.000 charging
2026-10-08T21:49:30 5.000 charging
2026-10-08T21:49:43 6.000 charging
...
2026-10-08T22:26:23 78.000 charging
2026-10-08T22:26:53 79.000 charging
2026-10-08T22:27:19 80.000 pending-charge

The file name includes the battery's model; there is also a generic_id file, which you can ignore. The ... stands for 71 lines we left out (file lines 4 to 74); every other line is verbatim.

pending-charge is UPower's state for a battery on AC that isn't charging. For reference, the battery's state on the day of the evidence run:

  model:                02DL004
    state:               charging
    charge-cycles:       284
    percentage:          55%
    capacity:            100%

What about the start threshold?

Ours is still at 0; we only set the end value. The kernel calls the start threshold "a battery percentage level, below which charging will begin", but neither doc says what 0 does. We haven't watched our battery sit at 80 long enough to see when it starts charging again.

If you want a gap, so the battery drains to, say, 75 before topping up, set both values. Write the end value first and keep the start value below it. We haven't run the two-value version on this laptop.

If you use TLP

TLP has its own threshold settings, START_CHARGE_THRESH_BAT0 and STOP_CHARGE_THRESH_BAT0 (TLP docs). If you enable those as well as a service like ours, two tools write the same file, so use one or the other. Our machine doesn't have TLP:

tlp unknown ok not-installed

Is 80% the right number?

Our take: 75 to 80 is a common choice for a laptop that's always plugged in, and it's what we use. We haven't measured battery wear ourselves, so we're not quoting a lifespan figure.

HackHour Weekly, every Wednesday

One email a week: the week's hack and what changed. Unsubscribe anytime.

What's in an issue

Sources

Platform facts in this guide link to these pages. Last checked .

  1. thinkpad_acpi: Battery charge control, Linux kernel documentation
  2. sysfs-class-power ABI, Linux kernel documentation
  3. Battery care settings, TLP documentation

Revision history

RevDateChange
AFirst published.

Errata

No corrections so far. Spotted one? Tell us through the site chat.