Android battery drain comes from background work the OS cannot defer, not from “unused apps” sitting in memory. Since Android 6.0, Doze, App Standby, and App Standby Buckets decide when your apps run, sync, and wake the CPU. This guide explains how those layers work, which settings change anything, and how to find the process draining your battery with adb.
Quick Takeaways
- Doze and App Standby Buckets defer jobs, alarms, and network access automatically. Most users gain nothing from task killers or “booster” apps.
- Wakelocks, exact alarms, foreground services, and badly behaved push or sync loops cause most real drain. Screen-on time and cellular signal come next.
- Per-app Battery usage settings (Unrestricted, Optimized, Restricted) are the only per-app lever worth touching.
adb shell dumpsys batterystatsand Battery Historian show what actually kept the device awake.
| Layer | Introduced | Scope | What it limits |
|---|---|---|---|
| Doze | Android 6.0 | Device-wide | Network, jobs, syncs, standard alarms |
| Light Doze | Android 7.0 | Device-wide | Subset of Doze while the screen is off and the device is moving |
| Background execution limits | Android 8.0 | Per-app | Background services, implicit broadcasts |
| App Standby Buckets | Android 9 | Per-app | Job frequency, alarms, high-priority FCM |
| Restricted bucket | Android 12 | Per-app | Strictest limits on jobs and alarms |
How Android Saves Power
Doze and Light Doze
Doze engages when the device is unplugged, stationary, and has the screen off for a period. The system suspends network access, defers jobs and syncs, and ignores standard alarms. It opens periodic maintenance windows so apps can catch up. The gaps between windows grow longer the longer the device stays idle.
Light Doze (Android 7.0+) applies a lighter subset of those restrictions when the screen is off but the device is moving, such as in a pocket or bag.
Apps can still get time-critical work done through high-priority FCM messages or setExactAndAllowWhileIdle() alarms. The system rate-limits both.
App Standby Buckets
Android 9 introduced App Standby Buckets. The system assigns each app to a bucket based on how recently and how often you use it. Google’s documentation says the bucket determines how often an app’s jobs run and how often it can trigger alarms. These restrictions apply only on battery power, not while charging.
| Bucket | Meaning | Restriction level |
|---|---|---|
| Active | You’re using the app now | Minimal |
| Working set | Used regularly | Mild |
| Frequent | Used often, not daily | Stronger; caps high-priority FCM |
| Rare | Seldom used | Strong |
| Restricted | Added in Android 12; heavy resource use or bad behavior | Highest |
| Never | Installed, never opened | Severe |
On Android 13 and higher, an app you don’t open for 8 days can land in the Restricted bucket unless it qualifies for an exemption. Android 12 used 45 days.
Adaptive Battery uses on-device machine learning to predict which apps you’ll open next and places them accordingly. Without the prediction model, the system falls back to recency of use.
Battery Saver vs. Adaptive Battery
| Feature | Trigger | Scope | Effect |
|---|---|---|---|
| Battery Saver | Manual or low-charge threshold | Device-wide | Limits background activity, may reduce performance and visual effects |
| Adaptive Battery | Always on (if enabled) | Per-app | Assigns standby buckets from usage patterns |
| Doze | Idle, unplugged, screen off | Device-wide | Defers network, jobs, alarms |
| Background restriction | User or system action | Per-app | Blocks background work almost entirely |
OEMs add their own layers (Samsung’s sleeping apps, Xiaomi’s autostart controls). They behave differently from AOSP, so test on your actual device.
Step-by-Step: Cut Drain on a Stock Android Device
Prerequisites
- Android 12 or newer (menu names below follow stock/Pixel Android)
- Optional: a PC with Android platform-tools and USB debugging enabled for the diagnostic section
1. Check where the drain is
Open Settings > Battery > Battery usage. Look at screen time vs. background time per app. An app with high background time and little screen time is your first suspect.
2. Set per-app background behavior
Open Settings > Apps > [app] > App battery usage (the label varies by OEM). You’ll see three modes:
| Mode | Behavior | Use for |
|---|---|---|
| Unrestricted | No limits on background work | Messaging or health apps that must deliver on time |
| Optimized | System decides using Doze, buckets, and usage | Default for nearly everything |
| Restricted | Background work largely blocked | Apps that misbehave and you rarely open |
Do not set everything to Unrestricted. That defeats Doze and App Standby. AOSP guidance says unnecessary exemptions undermine the benefits of both.
3. Fix the usual suspects
- Location: In Settings > Location > App permissions, change “Allow all the time” to “Allow only while using the app” wherever possible.
- Background data: Use Settings > Network & internet > Data Saver for apps that sync constantly.
- Notifications: Apps that wake the device for engagement pings (social, shopping, games) cost battery. Turn those channels off.
- Display: Enable adaptive refresh rate or lower the fixed rate. Cut screen timeout. Dark mode helps on OLED panels.
- Connectivity: Turn off Wi-Fi/Bluetooth scanning in Settings > Location > Location services if you don’t use nearby-device features.
4. Remove what you don’t use
Uninstall or disable apps you haven’t opened in months. A Never or Rare bucket app already has strict limits. An app that still wakes the device after that is a clear candidate for removal.
Diagnose Drain with ADB
The settings UI shows percentages. adb shows causes.
Reset and capture battery stats
# Clear previously collected stats so the report starts fresh
adb shell dumpsys batterystats --reset
# (Unplug the phone, use it normally for several hours, then reconnect)
# Dump readable stats to a text file
adb shell dumpsys batterystats > batterystats.txt
# Capture a full bug report (Android 7.0+ outputs a .zip)
adb bugreport bugreport.zip
--reset clears the existing stats. The device collects battery data continuously, and without a reset the output gets very large. The bug report feeds Battery Historian, which converts the data into an HTML timeline you view in the browser.
Track wakelocks in detail
# Record timestamps for every userspace wakelock transition
adb shell dumpsys batterystats --enable full-wake-history
By default, Android keeps aggregate wakelock totals but not per-transition timestamps. The full history log overflows within hours, so use this for short test runs of three to four hours.
Run Battery Historian
# Start the Battery Historian web UI (requires Docker)
docker run -p 9999:9999 gcr.io/android-battery-historian/stable:3.1 --port 9999
Open http://localhost:9999, upload bugreport.zip, and look for long bars under Wakelock, Alarm, JobScheduler, and Mobile radio active. Hover over a bar to see the owning process.
Check an app’s standby bucket
# Show the standby bucket for one package
adb shell am get-standby-bucket com.example.app
# List buckets for all packages (omit the package name)
adb shell am get-standby-bucket
# Force a bucket for testing
adb shell am set-standby-bucket com.example.app rare
Valid values for set-standby-bucket include active, working_set, frequent, and rare. Use this to test how an app behaves when throttled. Don’t use it as a permanent fix, because the system reassigns buckets on its own.
Force Doze on a test device
# Pretend the device is unplugged
adb shell dumpsys battery unplug
# Enter deep Doze immediately
adb shell dumpsys deviceidle force-idle
# Step through Doze states one at a time
adb shell dumpsys deviceidle step
# Exit Doze and restore normal charging state
adb shell dumpsys deviceidle unforce
adb shell dumpsys battery reset
force-idle skips the idle timers so you can see whether pushes, alarms, and jobs behave while the device is dozing. Always run battery reset afterward, or the device keeps reporting itself as unplugged.
Test Battery Saver behavior
# Turn on low power mode
adb shell settings put global low_power 1
# Turn it off
adb shell settings put global low_power 0
What Changed in Recent Android Versions
Each Android release tightens background rules a bit more. A few points from Google’s developer documentation:
- Android 16: Background jobs started by an app in the Active bucket get a generous runtime quota.
- Android 17 (API 37): The platform introduces app memory limits based on total device RAM. Google says the limits are conservative and target extreme leaks and outliers that cause UI stutter, higher battery drain, and apps being killed. It also hardens background audio, so apps need user-initiated intent to start playback or request audio focus from the background.
- Exemption requests: Apps that ask for
REQUEST_IGNORE_BATTERY_OPTIMIZATIONSface stricter Google Play policy review, and it should only be used for narrow use cases.
For users, the practical effect is that older apps may behave differently after an OS upgrade. Check Battery usage a few days after updating before blaming the update itself.
Troubleshooting Real-World Scenarios
Scenario 1: Phone loses 15-20% overnight
- Check Settings > Battery > Battery usage for the overnight window. Look for an app showing hours of background time.
- Run
adb shell dumpsys batterystatsafter a reset and a night unplugged. Search the output for Wake lock entries sorted by duration. - Set the offending app to Restricted, or uninstall it.
- Confirm the device actually enters Doze with
adb shell dumpsys deviceidleand check the reported state.
Weak cellular signal is another common cause. The modem works harder to hold a connection. Enable airplane mode overnight to test.
Scenario 2: Messaging notifications arrive late
You (or the OEM) are over-restricting the app, or it landed in a low standby bucket.
- Set the app to Unrestricted in its battery settings.
- Check the bucket with
adb shell am get-standby-bucket <package>. Rare or Restricted explains the delay. - On OEM skins, also enable autostart or “allow background activity” in the vendor’s own menu. These are separate from stock Android settings.
Apps that use high-priority FCM messages generally behave better than apps that keep their own persistent connection.
Scenario 3: Battery drains fast right after an OS update
The system re-indexes media, optimizes apps, and rebuilds usage predictions for a day or two after major updates. Adaptive Battery also needs time to relearn your patterns. Wait two or three full charge cycles. If drain persists, capture a bug report and check wakelocks.
Scenario 4: One app shows “background usage” despite being closed
Swiping an app away from recents does not stop its scheduled jobs, alarms, or push handlers. It only stops the foreground process. Use Restricted mode or force stop it from App info if it still misbehaves.
Settings That Don’t Help
| Habit | Reality |
|---|---|
| Task killers and “RAM boosters” | Force-closed apps restart, which costs more CPU and battery than leaving them cached |
| Turning off Adaptive Battery | Removes the per-app optimization that defers background work |
| Marking everything Unrestricted | Disables the limits Doze and standby buckets apply |
| Disabling Wi-Fi permanently on mobile data | Cellular uses more power per byte than Wi-Fi in most conditions |
| Calibrating the battery by draining to 0% | Modern lithium-ion cells don’t need it, and deep discharge wears them faster |
Battery Health and Charging Habits
Software tuning only goes so far. Cell wear sets the ceiling.
- Keep daily charge between roughly 20% and 80% when convenient. Many phones offer an Adaptive charging or charge-limit option in battery settings.
- Avoid heat. Charging under a pillow or leaving the phone on a car dashboard degrades the cell faster.
- Check battery health where your device exposes it. Pixel phones on recent Android versions show charge cycles and health under battery settings. Samsung exposes similar data in its Members app and diagnostics menu.
- If a two-to-three-year-old phone no longer lasts a day even after clean-up, a battery replacement often helps more than any setting.
FAQ
Does Doze mode drain or save battery?
Doze saves battery. It defers network access, jobs, syncs, and standard alarms while the device is idle, stationary, and unplugged. It runs periodic maintenance windows so apps can catch up. Apps that need immediate delivery use high-priority FCM messages, which bypass most deferral.
Should I use Restricted or Optimized battery mode?
Use Optimized for nearly all apps. It lets the system adapt using Doze and standby buckets. Choose Restricted only for apps that misbehave and that you rarely open, since it can block background sync and notifications. Choose Unrestricted only when timely background delivery matters more than battery, as with some messaging or medical apps.
How do I find which app is draining my Android battery?
Open Settings > Battery > Battery usage and compare background time to screen time. For deeper analysis, run adb shell dumpsys batterystats --reset, use the phone unplugged for several hours, then capture adb bugreport and load it into Battery Historian. Long wakelock, alarm, or mobile radio bars point to the cause.
What is the Restricted app standby bucket?
Restricted is the most limited App Standby Bucket, added in Android 12. It applies the strongest limits on jobs and alarms. On Android 13 and higher, the system can place an app there after about 8 days of no interaction, unless the app qualifies for an exemption.




