Zygote
Memory, lifecycle & powernerd

Battery and thermal

How Android attributes power to apps, why a hot phone throttles before the battery dies, and what Adaptive Battery actually predicts.

11 minAPI 21–37 · 17interactivequizverified 2026-10-27

A phone has two limits that look unrelated and are not: the battery's energy and the chassis's ability to dissipate heat. An app that drains the battery also heats the phone, and a hot phone throttles the CPU and GPU — so the same code gets slower as it runs. Understanding both is understanding why a benchmark score on a cold phone is not the score on a warm one.

TL;DR#

  • Power is dominated by the screen, the radio and CPU wakeups — in that order for most apps.
  • Android attributes power to apps through wakelocks, jobs, alarms and sensor usage, not by measuring each app's current draw.
  • Adaptive Battery (API 28Android 9) uses on-device prediction to restrict apps it expects the user will not use soon.
  • Thermal throttling reduces CPU and GPU clocks as the device heats; PowerManager.getThermalHeadroom reports how close the device is to that limit.
  • The modern approach to power debugging is a Perfetto trace with power counters, not batterystats alone.

Mental model#

Think of a car's fuel efficiency.

The engine is the CPU: it burns fuel proportional to work, and idling still burns some.

The air conditioning is the screen and radio: a constant, large drain that dwarfs everything else when it is on.

The radiator is the thermal design: it can only dissipate so much heat, and when the engine runs hot, the engine management limits power to protect it.

Where the analogy breaks#

A car's fuel gauge is a single number. Android's attribution is a model: it infers which app caused a wakeup, and a wakeup's cost depends on what the CPU did while awake. Two apps that wake the device the same number of times can have very different costs if one does 5 ms of work and the other does 500 ms.

The big picture#

Loading diagram…
Text description of this diagram

A Doze timeline showing when the device is awake, in light Doze and in deep Doze, with maintenance windows. Power consumption follows this shape: awake periods are expensive, Doze periods are cheap, and the maintenance windows are the bursts of activity. Widening windows are why an idle phone's battery curve flattens over time.

The timeline is also a power graph. The device's energy use is roughly proportional to the area under the awake regions — which is exactly what Doze is designed to shrink.

Deep dive#

What actually drains the battery#

For a typical phone, the big consumers are:

  1. The display. Backlight and panel power dominate when the screen is on, and nothing an app does in the background can compete.
  2. The cellular radio. Transmitting, and especially maintaining a connection in a weak signal, is expensive. A single request that wakes the radio can cost more than minutes of CPU.
  3. CPU wakeups. Each wakeup has a fixed cost to leave and re-enter a low-power state, plus the work done while awake.
  4. Sensors and GPU, usually smaller but relevant for games and navigation.

An app's power impact is therefore mostly a function of how often it wakes the device and what it does while awake, not of how much CPU time it uses in total.

Wakelocks#

A wakelock is a request to keep the CPU or screen awake.1 The screen wakelock is held by the system when the display is on; partial wakelocks can be held by apps to keep the CPU running while the screen is off.

Partial wakelocks are the classic battery bug: an app holds one while doing background work and forgets to release it, so the CPU never sleeps. Modern Android makes this harder — Doze ignores wakelocks — but a wakelock held while the device is awake still prevents the CPU from idling.

How attribution works#

batterystats does not measure current per app. It records events — wakelocks acquired and released, jobs run, alarms fired, GPS used, radio active — and estimates the energy cost of each from a device-specific power profile.

The result is an attribution, not a measurement. That is why two tools can disagree about which app used the most power: they are applying different models to the same events.

Battery Historian was the classic way to read this data: a batterystats dump rendered as a timeline of state changes, with wakelocks, jobs and radio activity on separate rows. It is still useful for a long historical view, even though Perfetto is better for a live trace.

Adaptive Battery#

API 28Android 9 introduced Adaptive Battery, which uses an on-device model to predict which apps the user is likely to use soon and restricts the rest more aggressively.2

It is the same idea as App Standby buckets, with prediction instead of pure recency. The practical consequence for an app is that its background work may be restricted before the user has stopped using it, if the model predicts they will not.

Thermal throttling#

Every phone has a thermal budget. When the SoC approaches it, the platform reduces CPU and GPU clocks, and in extreme cases reduces charging current or brightness.

For an app, this means a benchmark or a long render that runs fast for two minutes can slow down significantly after five. The effect is not uniform: it depends on the device's cooling, the ambient temperature, and whether the phone is charging.

PowerManager.getThermalHeadroom reports an estimate of how close the device is to throttling, as a value where 1.0 is the threshold. An app can use it to reduce its own load before the system forces it.

Measuring power properly#

The honest measurement is a trace with power counters. Perfetto can record power counters alongside CPU and GPU tracks, so you can see the correlation between an app's activity and the device's power state.

dumpsys batterystats remains useful for a summary and for historical data, but it is an estimate built from events. Treat it as evidence, not as a measurement.

The charging dimension#

Charging changes the thermal picture: a phone charging while gaming heats from two sources, and many devices reduce charging current when the SoC is hot. This is why "plugged in" is not always faster — it can be hotter and therefore slower.

What the radio actually does#

A cellular radio has several states, from a high-power active state to a low-power idle one, and transitions between them cost energy. A single small request can wake the radio, hold it in an active state for a fixed tail time, and then let it sleep — so the energy cost of a request is dominated by the tail, not the payload.

Ten 1 KB requests spread over a minute cost far more than one 10 KB request, because each one pays the tail again. That is the argument for batching, and the reason WorkManager's constraints include network state.

Why "background" is the hard case#

When the screen is on, the device is already in a high-power state and an app's marginal cost is small. When the screen is off, every wakeup pulls the CPU and often the radio out of a low-power state, and the cost is paid by whatever battery remains.

This is why the restrictions target background work specifically, and why an app that does something useful while visible is barely regulated at all.

Thermal throttling and the user's experience#

Throttling is not a failure; it is the device protecting itself. But it produces a user-visible effect: a game that runs at 60 fps for two minutes and then 40 fps for ten looks like the app got worse, not like the phone got hot.

An app that monitors thermal headroom can degrade gracefully — lower the resolution, reduce the effect quality, cap the frame rate — and produce a smoother experience than one that fights the throttle.

The measurement problem#

Power is hard to measure because it is a product of voltage, current and time, and phones do not expose per-app current. Everything is inferred from events and a device-specific power profile.

That means two devices can attribute the same behaviour differently, and a change that improves one may not improve the other. The only reliable method is to measure on the device you care about, over a realistic usage pattern, with a trace rather than a summary.

What Adaptive Battery predicts#

The model uses usage signals — launches, notifications tapped, time of day, charging patterns — to estimate whether an app will be used soon. If not, it restricts.

For an app, the implication is that being used is the signal that keeps it unrestricted. An app that is installed but rarely opened will be treated as low priority, and no amount of background correctness will change that.

How it evolved#

API 1–API 20Event attributionbatterystats infers energy from eventsAPI 1
API 21 →JobSchedulerdeferrable work becomes a platform conceptAPI 21
API 23 →Doze and Standbysystem-wide and per-app throttlesAPI 23
API 28 →Adaptive Batteryprediction joins recencyAPI 28
Background and power changes12 releases
APIVersionWhat changed
11.0
  • The original android.* SDK: Activity, Service, BroadcastReceiver, ContentProvider
174.2 Jelly Bean
  • Daydream service
194.4 KitKat
  • AlarmManager becomes inexact by default for targeting apps
215.0 Lollipop
  • JobScheduler
  • Implicit service intents restricted for targeting apps
268.0 Oreo
  • Background service limits
289 Pie
  • Foreground service permission
2910
  • Background activity starts restricted
3011
  • Background location requires a second request
3112
  • Exact alarms need SCHEDULE_EXACT_ALARM
  • Foreground service launch restrictions from the background
3414 Upside Down Cake
  • Foreground service types required when targeting 34
  • User-initiated data transfer jobs
3515 Vanilla Ice Cream
  • Deprecated APIs: WindowInsetsController hiding, elevate the importance of foreground services
3616 Baklava
  • JobScheduler quota changes

Under the hood#

Curiosity corner#

  • A weak cellular signal can dominate an app's power use. The radio transmits at higher power when the signal is poor, so the same sync costs more in a basement than near a window.
  • Screen brightness is often the single largest variable in a battery test, which is why benchmark protocols fix it.
  • Throttling is why sustained performance is a different metric from peak performance. A phone that wins a short benchmark can lose a long one.

Try it#

Thermal status
adb shell dumpsys thermalservice | head -20
Example output
Thermal Status: 0
Thermal Headroom: 0.62
Wakelocks held
adb shell dumpsys power | grep -A3 "Wake Locks"
Example output
Wake Locks: size=2
PARTIAL_WAKE_LOCK  'SyncJob'  ACQ 120s  com.example.app
Battery stats summary
adb shell dumpsys batterystats --charged com.example.app
Example output
Estimated power use (mAh):
Capacity: 4500
Computed drain: 312
Screen: 148
Radio: 62
CPU: 51

Check yourself#

Check yourself

1 / 12

Why can clearing apps from the recents screen fail to save battery?

0 answered · 0 correct

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsOptimize for Doze and App Standbydeveloper.android.comaccessed 2026-10-27↩
  2. docsOptimize power usedeveloper.android.comaccessed 2026-10-27↩
  3. docsStandby bucketsdeveloper.android.comaccessed 2026-10-27↩
  4. docsLow-memory killer daemon (lmkd)source.android.comaccessed 2026-10-27↩
  5. docsPressure Stall Information (PSI)docs.kernel.orgaccessed 2026-10-27↩
  6. docsPerfetto documentationperfetto.devaccessed 2026-10-27↩
  7. docsdumpsysdeveloper.android.comaccessed 2026-10-27↩