Modern Android power management relies on App Standby Buckets to restrict background resource utilization based on how recently and frequently an application is used. Managed by the Usage Stats service, the operating system assigns every installed package to a dynamic standby tier—ranging from Active to Restricted. As an app shifts into lower buckets, the system limits its ability to execute background jobs, defer network requests, suppress high-priority FCM notifications, and throttle alarm triggers. When testing background synchronization reliability or diagnosing delayed push notifications, inspecting and manipulating standby tiers via the Android Debug Bridge (ADB) using dumpsys usagestats and am set-standby-bucket provides complete diagnostic control.
Understanding App Standby Bucket Tiers
The Android runtime categorizes applications into five primary standby buckets based on user engagement patterns:
| Bucket Tier | Numeric Value | Operating System Restrictions |
|---|---|---|
ACTIVE |
10 |
The app is currently in the foreground, running a foreground service, or actively interacted with by the user. No background execution or network limits apply. |
WORKING_SET |
20 |
The app is used frequently (e.g., daily). Minor restrictions apply; background jobs and alarms execute with minimal deferral. |
FREQUENT |
30 |
The app is used regularly but not daily. Alarms and background jobs are batched and deferred up to several hours. |
RARE |
40 |
The app is used infrequently. Strict limits apply: jobs run in narrow 2-hour maintenance windows; network access is severely restricted. |
RESTRICTED |
45 |
Heavily restricted tier (often applied by Android battery optimization for high-drain apps). Cannot trigger alarms or jobs without explicit user launch. |
Inspecting App Standby States with dumpsys usagestats
To inspect active bucket allocations and engagement timestamps across all packages on your device, connect via ADB and run:
adb shell dumpsys usagestats
Because the full usage stats dump outputs extensive historical event ledgers, filter the output to isolate standby bucket allocations:
adb shell dumpsys usagestats | grep -A 10 "App Standby States:"
To query the specific standby bucket of a single target package directly:
adb shell am get-standby-bucket com.example.myapp
The command returns the current numerical bucket identifier (such as 10 for Active, 20 for Working Set, or 40 for Rare).
Auditing Historical Interaction Timestamps
The Usage Stats daemon tracks exact timestamps indicating when an app was last launched, when its notifications were interacted with, and when user engagement ceased. Search the dump for your target package:
adb shell dumpsys usagestats | grep -A 15 "package=com.example.myapp"
The output reports granular telemetry:
package=com.example.myapp:
currentBucket=20
lastUsedTime=1730976120412 (2026-11-07 10:42:00)
lastUsedByUserTime=1730976120412
lastPredictedBucket=20
bucketReason=u-f (USER_INTERACTION)
The bucketReason code reveals why the app was placed in that bucket:
u-f(USER_INTERACTION): The user explicitly opened the app or interacted with a notification.t-f(TIMEOUT): The app transitioned downward due to elapsed inactivity timers.p-f(PREDICTION): Machine learning battery models predicted usage probability.s-f(SYSTEM): System framework forced a bucket override.
Simulating Standby Tiers During Automated Testing
To test how an application behaves when battery restrictions are enforced, you can manually force the app into any standby bucket using the am set-standby-bucket command without waiting days for timeout triggers.
To force an application into the Rare bucket (to test deferred job scheduling):
adb shell am set-standby-bucket com.example.myapp rare
To simulate severe battery saver throttling by forcing the Restricted bucket:
adb shell am set-standby-bucket com.example.myapp restricted
To return the app to unconstrained foreground execution (Active):
adb shell am set-standby-bucket com.example.myapp active
Verify that the override applied immediately:
adb shell am get-standby-bucket com.example.myapp
Testing Battery Optimization and Job Scheduling Compliance
While an app is forced into rare or restricted mode, trigger a background work request using Android WorkManager or JobScheduler:
adb shell cmd jobscheduler run -f com.example.myapp 101
If the app correctly conforms to Android power management guidelines, the job will remain enqueued until an active maintenance window opens, or will execute within strict execution caps. Reviewing system behavior under simulated buckets ensures that critical sync routines do not fail unexpectedly in production user environments.