ra-yavuz › inhibit-charge

inhibit-charge logo: a battery inside a small house

inhibit-charge

Park your Linux laptop battery at a target charge level using the kernel's inhibit-charge mode. AC powers the system, the battery sits idle. No trickle cycling, no slow drift.

Quick install (Debian / Ubuntu)

One line. Sets up the signed ra-yavuz apt repo if not already added, refreshes the package index, installs inhibit-charge, and adds you to the inhibit-charge group. Idempotent, safe to re-run:

sudo bash -c 'set -e; install -m 0755 -d /etc/apt/keyrings && curl -fsSL https://ra-yavuz.github.io/apt/pubkey.gpg -o /etc/apt/keyrings/ra-yavuz.gpg && echo "deb [signed-by=/etc/apt/keyrings/ra-yavuz.gpg] https://ra-yavuz.github.io/apt stable main" > /etc/apt/sources.list.d/ra-yavuz.list && apt update && apt install -y inhibit-charge && usermod -aG inhibit-charge "${SUDO_USER:-$USER}"'

Or via the bundled installer script (equivalent, with hardware compatibility checks and a friendlier output summary):

curl -fsSL https://raw.githubusercontent.com/ra-yavuz/inhibit-charge/main/scripts/get.sh | sudo bash

If you already added the ra-yavuz apt repo earlier, all you need is sudo apt update && sudo apt install inhibit-charge. The sudo apt update step is required: without it apt will not see new packages or new versions. Future upgrades: sudo apt update && sudo apt upgrade. Full removal: sudo apt purge inhibit-charge. Other install paths (manual apt setup, single .deb, from source) appear further down on this page.

What it does

Most Linux battery tools (TLP, GNOME, KDE, framework-tool) cap charging with start/end thresholds. That stops the battery at, say, 60% but the cell still cycles: it self-discharges to the start threshold, the charger tops it back up, and the loop repeats every few hours. Each of those mini-cycles wears the battery.

inhibit-charge uses a different kernel feature (charge_behaviour=inhibit-charge on /sys/class/power_supply/BAT*) to hold the battery at the target indefinitely while AC drives the system. When you unplug, it switches back to auto so the battery discharges normally.

Two modes

The CLI is inhibit-charge:

Optional: terminal greeting

UI candy for the user: the current battery state printed at the top of every new interactive shell. Open a new terminal tab, see your battery state. Not a system MOTD, not a PAM login banner, not headless-server territory. Just a snippet sourced by every interactive shell.

Disabled by default. No sudo needed to toggle if you are in the inhibit-charge group:

$ inhibit-charge motd
Greeting enabled. The current battery state will be shown at the top
of every new interactive shell (terminal tabs, SSH, console).

$ inhibit-charge motd off
Greeting disabled.

How it works: the package ships /etc/profile.d/50-inhibit-charge.sh, which every interactive shell sources. The script short-circuits unless /var/lib/inhibit-charge/motd-enabled exists, so the default install is silent. The toggle just creates or removes that flag file. dpkg owns both, so apt purge removes them cleanly.

Platform support

Tested on Ubuntu (Linux only). Linux is the only supported OS. The tool is built on a Linux kernel feature (charge_behaviour=inhibit-charge on /sys/class/power_supply/BAT*) that does not exist on macOS or Windows. WSL2 is not supported either: WSL2 runs a Linux kernel inside a Hyper-V VM and does not expose host battery sysfs to the guest, so the kernel feature is unreachable from inside the WSL distro.

Hardware support

Requires Linux kernel ≥ 5.17 and a driver that exposes charge_behaviour with inhibit-charge listed. The daemon refuses to start on unsupported hardware with a clear error.

TierHardwareDriverStatus
1ThinkPads (most since X220-ish)thinkpad_acpiworks
1Chromebooks / ChromeOS-EC laptopscros_ecworks
2Framework laptopsframework_laptopworks on recent EC firmware
2System76 laptopssystem76_acpivaries by model
2Some ASUS / IdeaPadasus_wmi, vendor driversvaries
3Most Dell, HP, MSI, Razer(no inhibit-charge)not supported, use TLP for thresholds

Quick check

cat /sys/class/power_supply/BAT0/charge_behaviour
# expect to see: [auto] inhibit-charge ...

Install via apt repository (recommended)

Adds the ra-yavuz apt repository, installs the package, adds you to the inhibit-charge group. Idempotent, safe to re-run.

The inline one-liner (no script, no curl | bash):

sudo bash -c 'set -e; install -m 0755 -d /etc/apt/keyrings && curl -fsSL https://ra-yavuz.github.io/apt/pubkey.gpg -o /etc/apt/keyrings/ra-yavuz.gpg && echo "deb [signed-by=/etc/apt/keyrings/ra-yavuz.gpg] https://ra-yavuz.github.io/apt stable main" > /etc/apt/sources.list.d/ra-yavuz.list && apt update && apt install -y inhibit-charge && usermod -aG inhibit-charge "${SUDO_USER:-$USER}"'

Or via the bundled installer script (equivalent, with hardware compatibility checks and a friendlier output summary):

curl -fsSL https://raw.githubusercontent.com/ra-yavuz/inhibit-charge/main/scripts/get.sh \
  | sudo bash

Prefer to read it first? Same result, two commands:

curl -fsSL https://raw.githubusercontent.com/ra-yavuz/inhibit-charge/main/scripts/get.sh -o get.sh
less get.sh
sudo bash get.sh

If you already added the ra-yavuz apt repo earlier, all you need is sudo apt update && sudo apt install inhibit-charge. The sudo apt update step is required: without it apt will not see new packages or new versions. After install, you need a fresh shell session for the CLI to work as your user. Either run newgrp inhibit-charge, or log out and back in. Future upgrades: sudo apt update && sudo apt upgrade. Full removal: sudo apt purge inhibit-charge.

Step by step (manual repo setup, equivalent to the one-liner)
# 1. Trust the signing key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://ra-yavuz.github.io/apt/pubkey.gpg \
  | sudo tee /etc/apt/keyrings/ra-yavuz.gpg > /dev/null

# 2. Add the apt source
echo "deb [signed-by=/etc/apt/keyrings/ra-yavuz.gpg] https://ra-yavuz.github.io/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/ra-yavuz.list

# 3. Refresh the package index, then install and add yourself to the group
sudo apt update
sudo apt install inhibit-charge
sudo usermod -aG inhibit-charge $USER

Install directly from GitHub

Alternatively, download the latest .deb from GitHub Releases:

wget https://github.com/ra-yavuz/inhibit-charge/releases/latest/download/inhibit-charge_0.2.1-1_all.deb
sudo apt install ./inhibit-charge_0.2.1-1_all.deb
sudo usermod -aG inhibit-charge $USER

Install from source

For systems where you do not want to add the apt source, the repo ships a self-contained install.sh that handles everything (group, state dir, files, systemd unit, enable+start):

git clone https://github.com/ra-yavuz/inhibit-charge.git
cd inhibit-charge
sudo bash install.sh

Other subcommands: install.sh uninstall (remove files only), install.sh purge (remove everything including state), install.sh verify (status report). Idempotent.

After install, you need a fresh shell session before the CLI works: a new terminal tab in the same login session is not enough, because Linux freezes group lists at login. Either run newgrp inhibit-charge in your terminal, or log out and back in.

How it works

A small daemon (/usr/lib/inhibit-charge/inhibit-charged, around 150 lines of bash) watches the kernel power_supply subsystem via udevadm monitor and reacts to plug/unplug, capacity, and CLI events instantly. The CLI writes the desired state to /var/lib/inhibit-charge/{mode,target} and signals the daemon over SIGHUP, so changes apply with zero polling delay. A slow 5-minute fallback timer handles slow self-discharge while parked.

The recharge band scales with the target: max(2, target/10) percentage points. So target=60 parks in 54..60, target=25 in 23..25. Hardware-level start/end thresholds are also set to the same band as a safety net: if the daemon ever dies, firmware still holds the battery at the target.

Versus TLP, GNOME, KDE

These all expose start/end thresholds, which the kernel implements as "stop charging at end, resume at start." That's a cycling band, not a hold. inhibit-charge is a third state above thresholds: charging is actively blocked while AC drives the system. This package layers a tiny daemon on top of that kernel feature so it switches automatically with plug state, and exposes a two-mode UX (home / travel) over it. You can run TLP and inhibit-charge together.

Disclaimer / no warranty

This software writes to your laptop's battery management interface (/sys/class/power_supply/BAT*/charge_behaviour and the charge thresholds). It is provided as is, without warranty of any kind, express or implied. The author is not liable for any damage to battery, hardware, or data, however caused. Battery firmware and kernel drivers vary widely between vendors, models, and firmware revisions. Behaviour on your specific device may differ from what is described here. Long-term parking of a lithium-ion battery at a fixed state of charge has tradeoffs (calendar aging vs. cycle aging) that depend on your battery chemistry, temperature, and usage. Read the manufacturer's guidance for your laptop before relying on this tool. By installing or running this software you accept full responsibility for any consequences. Full text: repo README, license: MIT.