Limiting battery wear on laptops used mostly on AC power

I used this with good results on Dell and (s)Thinkpad laptops, used mostly on mains power: limiting the battery charge to something lower than 80% will radically reduce the battery wear. You can change the threshold to “100” and run the script manually if you need a full charge “for the road”.

Run sudo vi /etc/cron.daily/set_batt.sh in dom0 and paste the following:

#!/bin/bash
#
# Run daily from /etc/cron.daily (cron and/or anacron).
# Output directed to /dev/null in case you don't have the second battery.
#
CHARGE_START=54
CHARGE_END=60
(
for bnum in {0..1} ; do
	sleep "${bnum}"   # optimisation! :-)
	echo "${CHARGE_START}" > /sys/class/power_supply/BAT"${bnum}"/charge_control_start_threshold
	sleep 1
	echo "${CHARGE_END}" > /sys/class/power_supply/BAT"${bnum}"/charge_control_end_threshold
done
) >/dev/null 2>&1
#

The 1s delay is crucial! I had laptops crash without it.

You can check the current thresholds running, in dom0:
cat /sys/class/power_supply/BAT*/charge_st*

Lenovo and Dell both recommend to keep the charge between 50% and 60% for laptops rarely used on battery, and 75%-85% for laptops used on battery 1-2 times per week. Just edit the variables.

Enjoy!

6 Likes

What if I cycle between 25% and 85%, i.e. manually pull out the cable at ~85% and put it back in at ~25%…aside from cases where I might be away or might forget and the inconvenience of having to keep an eye on it, do you have a reference / data comparing this (cycling between moderate values) and leaving it static at some value regarding its impact on battery life or other battery characteristics?

25% is too low. The battery wear is increased every time you charge over 80% or discharge under 40%, and is drastically increased every time you charge over 90% or discharge below 20% (give or take 5%). I did not invent these numbers, there are a lot of good sources like this and the work done by the guys at https://apphousekitchen.com/ with AlDente for Macs.

Well, I don’t want and I don’t have to use the laptop on battery most of the time. Unplugging the cable will switch everything to “power saving mode”, reducing the brightness and throttling the CPU for example. That’s why I use this script - to be continuously on AC and not wear the battery out.

As for the reference, I posted it above. There are lots of other sites besides batteryuniversity.com, and the general opinion converges towards what I wrote.

3 Likes

The durability of a battery is usually defined by its remaining capacity after a certain number of charge/discharge cycles, so I think cycle between 25% and 85% is exactly wearing the battery even if you do not really need to use battery at that time. That’s why most guides focus on capping the maximum charged level instead of cycling between low level and high level.

The point is that when a battery is kept nearly full, it still wears even if you seems not to be using it.

Personally haven’t tried that script, but for whoever want this functionality, in many laptops there’s a BIOS setting for this.

In the newer Dells, yes. However people running Qubes tend to use older Lenovos which definitely don’t support this via the BIOS, not even the latest BIOS/firmware (which is 1.51 for T480 and X280-290).
Lenovo does the same thing as this script via their “Vantage” Windows software.

1 Like

60% might give you the theoretical best value, is pretty useless for anyone who actually needs to use the battery.

80% works because most people can get away with 20% less capacity, but with 40% you might as well just run the battery normal charging, it would take years for it to lose 40% capacity.

It’s just a suggested value! My batteries are shot anyway, and even at 2x 80% I get around 80 minutes of battery life.
With good batteries I would use 74 → 80, like AlDente recommend for Macs.

thanks for the great guide!
So from my understanding we are creating the set_batt.sh file,
and after that we need to run (in my case) anacron /etc/cron.daily/sett_batt.sh in dom0 terminal every time after reboot to have the changes come into effect?

I tried doing this but when I ran cat /sys/class/power_supply/BAT*/charge_st* I got the normal 0-100 values.
Note: I ran sudo nano instead of sudo vi, not sure if that made a difference (sudo vi was confusing to me).

In my case I had to run the command as root (sudo su), so that might be your problem. I didn’t try setting up a cron job for this yet, as I’m still testing it and mulling it over.

I’m unable to write those files (they don’t exist yet) even after sudo su.

I’m on a Librem 13

In my case they did exist and showed values 0 and 100 for start and end, respectively, FWIW.

IMHO if those files aren’t even there on your laptop then creating them won’t have any effect anyway, right? Maybe on your system you simply can’t make this customization for whatever reason or the files are in a different place? You can try asking on the Purism forum.

Edit: I’d also like to add that the linked BU article has some pretty serious methodological shortcomings, such as using data from experiments with very non-standard charge voltage, which may not translate to normal voltages, generalizing too much across chemistries and not normalizing for work done; in fact, when doing the latter with the same BU data, the 100%-25% cycle paradigm actually wins and the 75%-65% cycle loses, as for every cycle on the former far more energy is delivered than on the latter, which has to be accounted for when you compute the relevant wear value. See here for a more detailed write-up.

That said, the data is not representative as was pointed out and I for now do tend to think that keeping the laptop on AC power while having an outlet and capping charge to 70% unless I need more is probably a good idea.

2 Likes

Correct!

Correct!

Right. Those are system files, they appear only if your kernel recognizes the hardware. You cannot create them manually.

I wrote in the original post that “this works on Dells and Thinkpads” on which I tested. It may work on other hardware, but not on all hardware.

If the script is not working for you, then it’s worth listing the contents of each /sys/class/power_supply/BAT"${bnum}/ folder to verify the names of the threshold config files. On my system these are named charge_start_threshold and charge_stop_threshold, so (as in my case) the script may need to be modified accordingly.

1 Like

@SteveC maybe your files are also simply called differently, as for ephile?

Also, for anyone wanting to have this bound to a keyboard shortcut and thus needs to manage permissions differently, this works for me (don’t forget to chmod +x the script):
Edit: I discovered that for some reason the system mostly ignores the charge_control_start_threshold and charges to the end cap anyway, which, while better than constanly cycling e.g. 70-15, still wears out the battery more quickly than if it didn’t start charging every time I plug in the cord. I’ve modified the script now to check the current charge percentage, subtract 5 from it (since for some reason when I plug in the cord the percentage always drops a bit) and then sets the new thresholds below that, which in my case achieves what I want (no charging).

#!/bin/bash
CAPACITY=$(($(cat /sys/class/power_supply/BAT0/capacity) - 5))
sleep 1
sudo su -c 'echo '"$CAPACITY"' > /sys/class/power_supply/BAT0/charge_control_end_threshold'
sleep 1
sudo su -c 'echo '"$(($CAPACITY - 5))"' > /sys/class/power_supply/BAT0/charge_control_start_threshold'
sleep 1
START_THRES=$(cat /sys/class/power_supply/BAT0/charge_control_start_threshold)
END_THRES=$(cat /sys/class/power_supply/BAT0/charge_control_end_threshold)
notify-send "Limited battery thresholds" "start: $START_THRES\nend: $END_THRES"

The first difference (which I disregarded as likely system specific) is that I have only a BAT and an AC directory (no zero, no BAT1).

Cat-ing every single file in there there’s nothing obvious except two of the files contain a 0 and a 100 respectively. But their names are “alarm” and “capacity”.

I suppose “capacity” might be an end threshold; I could try setting it to 70 and see what happens. If it works that way I’d half-expect the laptop (currently fully charged) to discharge to that level, even though it’s plugged in.

Result: Even sudo su, then editing; it will not allow me to edit.

capacity, at least on my machine, is the current charge level as a percentage, so that won’t be it. You’re editing with echo "value" > file, right?

Aren’t those just showing the current settings? Can you really write to them?
In all the machines I tested, I had to write to something like:

/sys/class/power_supply/BAT{N,}/charge_control_start_threshold
/sys/class/power_supply/BAT{N,}/charge_control_end_threshold

and the current status can be read from:

/sys/class/power_supply/BAT{N,}/charge_start_threshold
/sys/class/power_supply/BAT{N,}/charge_stop_threshold

If you check my original posting, I mention this in the form of:

On my machine the files charge_start_threshold and charge_stop_threshold don’t exist, so I just read from the same files I write to.