KOTLIN · JETPACK COMPOSE SCAFFOLDING · ROOM + RETROFIT DATA LAYER · HILT DEPENDENCY GRAPH · GITHUB ACTIONS · BITRISE · GITLAB CI · MATERIAL 3 DESIGN SYSTEM GENERATION · TEST ENGINEERING SUITE · COMPLIANCE + LEGAL REVIEW · ARCHITECTURE DIAGRAM RENDER
UTC07:37:10
UP00:01
MOD · ARTICLE · PERFORMANCES/N · AX-ANDROIPUBLISHED
PerformanceSep 22, 202610 MIN
Your Crash Rate Is a Ranking Signal: Android Vitals, Wake Locks and the 2027 Memory Rules
Google Play demotes apps past a 1.09% crash or 0.47% ANR rate. Wake locks became a core vital in 2026, and memory limits arrive in February 2027.
By Rocky Elsalaymeh · Founder & Principal Consultant, Strategia-X
Stability Stopped Being an Engineering Metric
Most teams track crash rate the way they track build time: an internal health number, reviewed when it gets bad. Google Play does not treat it that way. It treats it as a ranking input.
The Android vitals documentation says so without hedging: "Core vitals are the most important metrics in Android vitals, and affect the visibility of your app on Google Play," and "if your app or game exceeds a bad behavior threshold, Play may reduce the visibility of your title. Play may also show users a warning on your store listing." The Play Console Help page adds the per-device consequence: "If your app has bad behavior on specific device models, Google Play will steer users on those devices away from these titles and towards others that are more suitable for them."
This is not new, and the reasons have been stated for years. In 2017 Google reported that "in an internal analysis of app reviews on Google Play, we noticed that half of 1-star reviews mentioned app stability." In 2022 it moved to user-perceived metrics because "we've seen a stronger correlation with uninstalls," and announced that users "may see a store listing warning if a title has a user-perceived crash rate or user-perceived ANR rate above 8% on their phone model starting November 30, 2022."
What is new is the scope. In the last twelve months the core vitals grew from stability to battery, and the next expansion, memory, has a date. A team that only watches crashes is watching one input to a ranking model that now has several.
The Thresholds, in One Table
Every number below is from the Android vitals overview. Play evaluates them over time: it "will generally consider the last 28 days of data when evaluating your app's quality but may act sooner in the event of a spike."
Core vital
Overall (average across devices)
Per phone model
Per watch model
User-perceived crash rate
1.09%
8%
4%
User-perceived ANR rate
0.47%
8%
5%
Excessive battery usage (watch faces)
1%
n/a
1%
Excessive partial wake locks
5%
n/a
n/a
The definitions matter as much as the numbers, because they count users, not events. User-perceived crash rate is "the percentage of your daily active users who experienced at least one crash while they were actively using your app," and the ANR equivalent is "the percentage of your daily active users who experienced at least one user-perceived ANR." One user hitting the same crash ten times counts once; ten users hitting it once each count ten times. That changes prioritisation: the crash that reaches the most people per day beats the crash with the most occurrences.
The per-device column is the one that surprises teams. An app comfortably under 1.09% overall can still cross 8% on one popular phone model, typically through an OEM-specific WebView, GPU driver or memory limit, and lose visibility for exactly the users on that model. Sort Play Console's crash clusters by device, not just by volume.
Wake Locks Joined the Core Vitals
Battery used to be a secondary metric. In November 2025 Google made excessive partial wake locks "generally available as a new core vitals metric to all developers," and defined it precisely: "We consider a user session excessive if it holds more than 2 cumulative hours of non-exempt wake locks in a 24 hour period," and "the bad behaviour threshold is crossed when 5% of an app's user sessions over the last 28 days are excessive." The penalty had a date: "Starting March 1, 2026, if your title does not meet this quality threshold, we may exclude the title from prominent discovery surfaces such as recommendations."
It arrived on schedule. Google's March 2026 update confirmed that "on March 1st, 2026, Google Play Store began rolling out the wake lock technical quality treatments," and listed the exemptions: a wake lock is exempt "if it is a system held wake lock that offers clear user benefits that cannot be further optimized, such as audio playback, location access, or user-initiated data transfer."
One caution: at the time of writing the Play Console Help page still describes the metric as a beta with a 3-hour definition, while both Google blog posts use 2 hours. Treat the newer, stricter definition as the one to engineer against, and check the figure your own Console shows.
The engineering answer has not changed in years, which is why this metric punishes neglect rather than difficulty. Background work belongs in WorkManager, which manages its own wake locks and respects the system's scheduling. A manual PowerManager.WakeLock should be the exception: always acquired with a timeout, always released in finally, and tagged so vitals can attribute it.
kotlin
// Prefer: let WorkManager hold (and release) the wake lock for you.val sync = OneTimeWorkRequestBuilder<SyncWorker>().setConstraints(Constraints(requiredNetworkType = NetworkType.CONNECTED)).build()
WorkManager.getInstance(context).enqueueUniqueWork("sync", ExistingWorkPolicy.KEEP, sync)// If you truly need a manual wake lock: bounded, released, attributable.fun<T>withWakeLock(context: Context, tag: String, block:()-> T): T {val pm = context.getSystemService(PowerManager::class.java)val lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"myapp:$tag")
lock.acquire(10*60*1000L)// hard ceiling: never an unbounded acquire()try{returnblock()}finally{if(lock.isHeld) lock.release()}}
Memory Is Next, and It Has a Date
The vitals overview now carries a warning with a deadline: "Apps exceeding the thresholds for memory usage, bitmap memory usage, or code optimization may see store visibility impact starting from February 2027." Play's technical quality requirements spell it out. "Memory usage is being introduced as new core vitals metrics, with two metrics: Memory usage (Anonymous RSS + Swap)" and "Bitmap memory usage." Evaluation uses the 90th percentile over the same 28-day window, and "this requirement only applies to mobile and tablet form factors."
The thresholds are tiered by device RAM and by app state. For apps (games have their own table), the published 90th-percentile limits include:
Device RAM tier
Foreground
User-perceived services
Background
4 GB
2 GB
1 GB
1 GB
6 GB
2.25 GB
1.25 GB
1.25 GB
8 GB
2.25 GB
1.5 GB
1.5 GB
12 GB
3.25 GB
1.75 GB
1.75 GB
The foreground numbers are generous for a well-behaved app. The background column is where apps get caught: an image cache sized for the foreground, a media player that keeps decoded frames after the user leaves, a WebView kept alive "for speed." Trim caches in onTrimMemory and when the app moves to the background, and measure the background state explicitly, because nobody looks at it in manual testing.
The same page introduces a code-optimization bar from February 2027: "You will need to achieve a minimum of 25% optimization, obfuscation and shrinking for any app uploads to Play Console," enforced for apps with more than 10 MB of DEX code (50 MB for games). An app over that DEX size that ships release builds with isMinifyEnabled = false is shrinking and obfuscating nothing. Google's answer is tool-agnostic: "You can use any tool, such as R8 or another app shrinker to achieve the minimum 25% thresholds." Our baseline profiles and R8 guide covers the R8 configuration.
ANRs: The Timeouts You Are Actually Racing
ANR rate has the lowest threshold of the stability vitals, 0.47% against 1.09% for crashes, and ANRs are harder to see in development because nothing throws. The ANR guide lists the triggers:
Trigger
Timeout
Input dispatch (key press or touch) not handled
5 seconds
startForegroundService without startForeground
5 seconds
BroadcastReceiver still running, app in foreground
5 seconds
Service onCreate / onStartCommand / onBind
"a few seconds"
JobService.onStartJob / onStopJob not returning
"a few seconds"
The fix is almost always the same: something slow ran on the main thread. Disk reads in onCreate, a synchronous SharedPreferences commit, a lock contended with a background thread, a large layout inflated on the first frame. StrictMode in debug builds catches the disk and network cases before they ship.
For the ANRs that do ship, stop relying only on Play's aggregated clusters. Since Android 11, ApplicationExitInfo "provides information about the reason for application exit," including the ANR trace captured before the process died, and on API 31 and higher, tombstones for native crashes. Read it on the next launch and upload it with your own context attached.
kotlin
// On next launch: why did the previous process die?funreportPreviousExits(context: Context, upload:(String, Long, ByteArray)-> Unit){if(Build.VERSION.SDK_INT < Build.VERSION_CODES.R)return// API 30+val am = context.getSystemService(ActivityManager::class.java)for(exit in am.getHistoricalProcessExitReasons(context.packageName,0,5)){when(exit.reason){
ApplicationExitInfo.REASON_ANR ->
exit.traceInputStream?.use{upload("anr", exit.timestamp, it.readBytes())}
ApplicationExitInfo.REASON_CRASH_NATIVE ->// tombstone on API 31+
exit.traceInputStream?.use{upload("native-crash", exit.timestamp, it.readBytes())}
ApplicationExitInfo.REASON_LOW_MEMORY ->upload("low-memory", exit.timestamp,"pss=${exit.pss}".toByteArray())}}}
Watch Vitals Like a Production Metric
A 28-day window means a bad week keeps hurting for a month. The only defence is to see regressions in days, not in the monthly review.
- Pull vitals into your own dashboards. The Play Developer Reporting API exists to "collect data about your app's quality from Android vitals, including crash rate, ANR rate, wake-up and wake-lock issues, and error stack traces." Alert on the per-device rates, not just the overall average.
- Gate releases on them. New releases get hourly crash and ANR granularity in Play Console for their first days; a staged rollout that only promotes when those numbers hold is the cheapest insurance against a ranking hit.
- Budget the new vitals now. Measure background memory at the 90th percentile on a 4 GB device, audit every manual wake lock, and turn on R8 for release builds before February 2027 turns each into a visibility problem.
- Prioritise by users affected. Because the rates count users, the crash that hits the most distinct daily users is the one to fix first, even if another has more raw events.
The framing to bring to planning: vitals are not a quality dashboard that engineering owns. They are a store-placement input the whole product depends on, and in 2027 there will be more of them.
MOD · TAKEAWAYS6 POINTSSUMMARY
Key Takeaways
1Google Play can reduce visibility and show store-listing warnings when an app exceeds a core vitals threshold, judged over the last 28 days.
2The stability thresholds are 1.09% user-perceived crash rate and 0.47% ANR rate overall, and 8% for either on a single phone model.
3Excessive partial wake locks became a core vital in November 2025, with discovery-surface penalties rolling out from March 1, 2026.
4From February 2027, memory usage (Anonymous RSS + Swap, and bitmaps) and a 25% code-optimization bar affect store visibility.
5ANRs fire at 5 seconds for input, startForeground and foreground broadcasts; ApplicationExitInfo (API 30+) recovers the trace on next launch.
6Pull vitals through the Play Developer Reporting API, alert per device model, and gate staged rollouts on them.
MOD · FAQ3 ENTRIESANSWERED
Frequently Asked
What are the Android vitals bad behavior thresholds?
User-perceived crash rate of 1.09% and ANR rate of 0.47% overall, 8% for either on a single phone model, and 5% of sessions with excessive partial wake locks. Exceeding them can reduce an app’s visibility on Google Play.
When do the Android vitals memory thresholds take effect?
Google states that apps exceeding the memory usage, bitmap memory usage or code optimization thresholds may see store visibility impact starting from February 2027.
What counts as an excessive wake lock?
Google’s 2025 definition is a user session holding more than 2 cumulative hours of non-exempt wake locks in 24 hours; the threshold is crossed when 5% of sessions over 28 days are excessive. Audio playback, location and user-initiated transfers are exempt.
MOD · BUILD · NEXTS/N · AX-CTA-0001READY
Ready to architect your next Android app?
ANDROID-ARCHITECT generates production-ready Kotlin code, architecture blueprints, and CI/CD configurations from plain-language descriptions. Start building for free.
ANDROID-ARCHITECT · CONSOLE
S/N · AX-1A-00001
STRATEGIA-X · ENGINEERED · IN · CALIFORNIA
Cookie Preferences
GDPRCCPA
We use cookies and similar technologies to provide core functionality, analyze traffic, and improve your experience. You control which categories are active. Essential cookies cannot be disabled.