DEV Community

Manu Shukla
Manu Shukla

Posted on • Originally published at ecorpit.com

0.47% ANR, 1.09% crashes: the Play Store limits that quietly hide your Android app

0.47% ANR, 1.09% crashes: the Play Store limits that quietly hide your Android app

Summary. Google Play sets 2 numbers that decide whether your Android app keeps its distribution: a user-perceived ANR rate of 0.47% and a user-perceived crash rate of 1.09%, both measured across all device models over a rolling 28-day window. Cross either and Play makes the app less discoverable. There is a second, harsher gate per device: at 8% on a single phone model, Play steers users on that model away and can put a warning on your store listing, a policy live since 30 November 2022. Lauren Mytton, Group Product Manager at Google Play, wrote when the bar was introduced that "we'd like developers to aim for per-phone stability metrics that are no worse than 2%". Most teams never see any of this, because nothing fails: no rejection email, no policy strike, just a slow decline in installs from a $25 developer account that is technically in good standing. The thresholds are percentages of daily active users, not of sessions, so a 1% crash rate on a 2 million DAU app is 20,000 people a day. An ANR fires after only 5 seconds of an unresponsive main thread. In India, where Android carries the overwhelming majority of the smartphone base and mid-range hardware dominates, per-device failures land first and hardest. This is fixable engineering work with a clear finish line.

What Play actually measures

Android vitals reports many metrics. Only 4 are core vitals, and core vitals are the ones that change your visibility on Google Play: user-perceived crash rate, user-perceived ANR rate, excessive battery usage for watch faces, and excessive partial wake locks, the last still in beta and not yet affecting discoverability.

The word doing the work is "user-perceived". A user-perceived crash is one the user was likely to notice, such as a crash while an activity is on screen or a foreground service is running. A user-perceived ANR is narrower still: Play currently counts only "input dispatching timed out" ANRs, the ones that hit while a person is tapping your interface. Both are normalised against daily active users, where a user on two devices in one day counts twice.

Core vital Overall bad behaviour threshold Per phone model threshold
User-perceived crash rate 1.09% of daily active users 8% of daily active users
User-perceived ANR rate 0.47% of daily active users 8% of daily active users
Excessive battery usage (watch face) More than 1% of watch face sessions More than 1% of sessions
Excessive partial wake locks (beta) More than 5% of battery sessions with wake locks over 3 hours Not applied while in beta
DAU / MAU core value Below 8% can trigger a store listing warning Not applied per device

Play generally evaluates the last 28 days, "but may act sooner in the event of a spike". Two other details change how you should read your own dashboard. Vitals data excludes uncertified device models and any install that did not come through Google Play, so sideloaded and alternative-store traffic is invisible here. And the data comes only from users who opted in to share usage and diagnostics, which means your Vitals number and your crash-reporting SDK's number will never match exactly. Both are right. They measure different populations.

The metrics nobody watches until they bite

Beyond the core vitals, Android vitals publishes a set of thresholds that shape user experience and reviews long before they show up in a stability chart.

Metric Play's trigger What it feels like to a user
Slow cold start 5 seconds or more to first frame The app looks broken on launch
Excessive slow frames Over 50% of frames above 16 ms render time Scrolling stutters
Excessive frozen frames Over 0.1% of frames above 700 ms The screen locks up mid-gesture
Stuck partial wake locks Any wake lock over 1 hour with the screen off Battery drains overnight
Excessive wake-ups More than 10 AlarmManager wake-ups per hour Battery drains, device warms
Background Wi-Fi scans More than 4 scans per hour in the background Battery drain attributed to your app
Background network usage More than 50 MB per day in the background Data charges the user did not expect
User loss rate Above 5% can trigger a store listing warning Uninstalls compound

Slow warm starts trip at 2 seconds and hot starts at 1 second. The frame budget of 16 ms comes from a 60 frames-per-second target, and Play breaks a slow frame down further so you can see the cause: missed vsyncs, input events over 24 ms, UI thread work over 8 ms, draw commands over 12 ms, and bitmap uploads over 3.2 ms.

Battery metrics deserve a specific warning for teams shipping in India and other price-sensitive markets. A user who sees your app at the top of the battery screen uninstalls it and leaves a one-star review about something you cannot reproduce on your desk.

Why ANRs are harder than crashes

A crash gives you a stack trace pointing at the line that failed. An ANR gives you a main thread that was busy or blocked, and the real cause is often somewhere else entirely.

The timeouts are short. Input dispatching times out after 5 seconds of an unresponsive main thread. A foreground broadcast receiver has 10 seconds to finish and a background one 60 seconds. If your app calls Context.startForegroundService() and the service does not call startForeground() within 5 seconds, that is an ANR too, with service timeouts of 20 seconds in the foreground and 200 seconds in the background.

The patterns behind most user-perceived ANRs are boring and repeatable:

  • Disk or database work on the main thread, especially a first-run migration or an oversized SharedPreferences commit.
  • Lock contention, where a background thread holds a lock the UI thread needs. The stack trace blames the UI thread, which is innocent.
  • Broadcast receivers doing real work instead of handing off to WorkManager.
  • Synchronous initialisation in Application.onCreate(), which grows every time a team adds an SDK.
  • Binder calls to a system service that is itself under pressure on a low-end device.

Play tells you where to look. Android vitals breaks ANRs down by ANR activity name, ANR type, device model, Android version and app version, so you can see whether one Activity, one OEM's Android build or one release is generating the rate. The multiple-ANR rate is the metric to watch for issue loops: users hitting the same block twice in a day are users who are about to uninstall.

A remediation sequence that works

Getting back under 0.47% is not a sprint of random optimisation. It is a sequence, and the order matters because each step tells you whether the next one is needed.

Week 1: instrument and segment. Pull 28 days of user-perceived ANR and crash data through the Play Developer Reporting API rather than screenshotting the console, because the API holds 3 years of history against the console's 90 days. Break the rate down by device model, Android version and app version. The output of this week is a ranked list of clusters with the number of affected users attached, not a plan.

Week 2: fix the top clusters, not the interesting ones. Play states it plainly: the higher the number of affected users in a cluster, the more it contributes to your rate. Three clusters usually carry the majority of a bad rate. Fixing the fourth-largest is engineering theatre until the top three are closed.

Week 3: attack the main thread structurally. Move disk, database and network work off it. Turn on StrictMode in debug builds so accidental main-thread I/O fails loudly in development. Audit Application.onCreate() and defer every SDK that does not have to initialise at launch, which usually also fixes the cold-start metric.

Week 4: verify on the devices that failed. Per-device thresholds are where most Indian and Southeast Asian apps get hit, because the install base sits on mid-range hardware with aggressive OEM battery management. Test on the specific models Vitals flagged, not on the newest device in the office.

Then hold the line. Wire the Reporting API into your release pipeline so a regression shows up as a build signal rather than a store-listing warning 28 days later. This is the part teams skip, and it is why the same app crosses the threshold twice in a year.

Phase Work Signal that it worked
Instrument Reporting API pull, cluster ranking by affected users A ranked list, not a hunch
Triage Fix the top 3 clusters Rate moves within one release cycle
Structural Main thread audit, StrictMode, deferred init Cold start and ANR rate fall together
Per-device Reproduce on flagged models Per-model rate drops below 8%
Hold Vitals thresholds in CI, alerting on anomalies Regressions caught pre-release

India-specific considerations

Android dominates the Indian smartphone base, and the install base skews toward mid-range and entry-level hardware with heavy OEM customisation. Three consequences follow.

The per-device threshold matters more here than the overall one. An app can sit comfortably under 1.09% overall and still be quietly hidden from users on a specific popular model, which in India can mean a large share of the addressable market. The overall number looks healthy while acquisition on that model dies.

OEM battery management interacts badly with wake locks and alarms. Aggressive process killing on some Indian-market devices produces ANR and low-memory-kill patterns that never appear on a Pixel. Reproduce on the flagged model or you will ship a fix that does nothing.

Data and battery cost real money to users on prepaid plans. The 50 MB per day background network threshold and the 10 wake-ups per hour threshold are not abstract policy limits in this market; they are the difference between an app staying installed and being cleared out during a storage cleanup. Storage and data discipline are covered further in our Android and Kotlin app development work.

One more piece of context on the economics: a Play developer account is a one-time $25 registration, but keeping an app visible is an ongoing engineering cost, and Play's service fee structure decides what the resulting installs are worth. We broke that down in our analysis of Google Play service fees and app economics.

Where this sits alongside your other Play deadlines

Vitals work competes for the same engineering hours as the compliance calendar, and the calendar wins by default because it has a hard date. The target API 36 Play Store deadline migration is the current example.

The order that works: do the compliance migration, then measure vitals on the migrated build, then remediate. A target SDK bump changes background execution behaviour, which changes your ANR profile. Remediating before the migration means measuring a build you are about to replace. Both pieces of work belong in the same release plan, which is how we structure enterprise mobile app development engagements.

Which data source to trust for which decision

Most teams run at least two stability data sources and then argue about which one is lying. Neither is. They answer different questions, and knowing which to open saves a week.

Android vitals is the only source that decides your distribution. It is field data from opted-in users on certified devices with Play-delivered installs, aggregated daily, and it is the exact dataset Play uses to apply the 0.47% and 1.09% thresholds. When the question is "are we about to lose visibility", this is the only number that counts. Its weakness is latency and detail: it updates daily, holds 90 days in the console, and does not give you a full stack trace with your own logging context attached.

A crash-reporting SDK is the source for diagnosis. It sees every install, including sideloads and alternative stores, reports within minutes, and carries breadcrumbs, custom keys and the user journey that preceded the failure. Its rate will differ from Vitals because the population differs, so treating its percentage as your Play compliance number is a mistake teams make once.

The Play Developer Reporting API sits between the two and is the piece most teams have not wired up. It exposes the same metric sets as the console with 3 years of history, which makes it the right source for release-over-release comparison, for alerting, and for putting a threshold check into CI. If a release pushes the user-perceived ANR rate up, you want that in a build report, not in a quarterly review.

Peer benchmarks are the fourth input and the most misused. Play Console lets you compare against a category benchmark or a custom peer group. That comparison is useful for a conversation with a product owner about how much stability work is worth funding. It is useless as a target, because your peer group's average tells you nothing about whether you are above 0.47%. The threshold is absolute.

The practical setup: Vitals for the verdict, the Reporting API for automation and trend, a crash SDK for the debugging session, and peer data only when someone asks whether the investment is justified. Test coverage on the failing paths is what keeps the fix from regressing, which is where QA and test automation earns its place in the same release plan.

What good looks like

Google's own guidance sets a target well below the enforcement line. Lauren Mytton, Group Product Manager at Google Play, wrote that although the per-phone bar started at 8%, developers should aim for per-phone stability metrics no worse than 2%. Treat 0.47% and 1.09% as the floor you must never approach, not the goal.

A practical set of internal targets: user-perceived ANR rate under 0.2%, user-perceived crash rate under 0.5%, no phone model above 2% on either, cold start under 2 seconds on your median device, and zero background wake locks over an hour. Teams that hold those numbers do not think about Play's thresholds at all, which is the point.

FAQ

What is the ANR rate limit on Google Play?

Google Play's overall bad behaviour threshold is a user-perceived ANR rate of 0.47%, meaning at least 0.47% of daily active users experienced a user-perceived ANR across all device models. There is a separate per-phone-model threshold of 8%. Exceeding either makes an app less discoverable.

What happens if my app exceeds the crash rate threshold?

Play reduces the app's discoverability, which can mean exclusion from recommendation surfaces. If the app exceeds the 8% per-device threshold on a phone model, Play steers users on that model elsewhere and may show a warning on the store listing. Store listing warnings have applied since 30 November 2022.

What counts as a user-perceived ANR?

Currently only ANRs of the "input dispatching timed out" type, which occur when the app fails to respond to input within 5 seconds. Play counts these because they always happen while the user is engaged with the app. Your overall ANR rate, which includes other types, will be higher.

Why does Play Console show a different crash rate than my crash SDK?

Android vitals only collects data from users who opted in to share usage and diagnostics, and excludes uncertified device models and installs that did not come through Google Play. A third-party SDK sees a different population. Both numbers can be correct while disagreeing.

How long does Play look back when judging quality?

Play generally considers the last 28 days of data when evaluating your app's quality, but may act sooner in the event of a spike. Android vitals holds 90 days of data in Play Console and 3 years through the Play Developer Reporting API, which is the better source for trend work.

Do wake locks affect Play visibility yet?

Excessive partial wake locks is a core vital but remains in beta, and exceeding its threshold does not currently make an app less discoverable. The threshold is more than 5% of battery sessions with one or more partial wake locks totalling over 3 hours. Stuck wake locks over an hour are reported separately.

What ANR rate should we actually target?

Lauren Mytton, Group Product Manager at Google Play, wrote that developers should aim for per-phone stability metrics no worse than 2%, well below the 8% enforcement bar. A practical internal target is a user-perceived ANR rate under 0.2% and a user-perceived crash rate under 0.5% overall.

Can a good overall rate hide a device-level problem?

Yes, and this is the common failure in the Indian market. An app can sit under the 1.09% overall crash threshold while exceeding 8% on one popular phone model, losing discovery and gaining a store listing warning for exactly the users on that device. Always review the per-model breakdown.

How eCorpIT can help

We run Android vitals remediation as a scoped engagement: pull 28 days of user-perceived crash and ANR data through the Play Developer Reporting API, rank clusters by affected users, fix the ones that move the rate, and reproduce on the specific device models Play flagged. eCorpIT is a Gurugram-based engineering organisation founded in 2021, assessed at CMMI Level 5 and ISO 27001:2022 certified, with senior-led Android teams and a Google partnership. The work usually pairs with mobile app maintenance and support so the thresholds stay met after the fix. If your Play Console is showing a bad behaviour warning, contact us and we will start with your Vitals data rather than a proposal.

References

  1. Monitor your app's technical quality with Android vitals — Play Console Help, on core vitals, metric definitions and bad behaviour thresholds.
  2. Raising the bar on technical quality on Google Play — Android Developers Blog, Lauren Mytton, 2 November 2022.
  3. Android vitals — Android Developers.
  4. ANRs — Android Developers, on ANR triggers and timeouts.
  5. Diagnose and fix ANRs — Android Developers.
  6. Crashes — Android Developers.
  7. View crashes and application not responding errors — Play Console Help.
  8. Play Developer Reporting API — Google for Developers.
  9. App startup time — Android Developers, on cold, warm and hot starts.
  10. Excessive battery usage — Android Developers, on wake locks and battery vitals.
  11. Compare your app's Android vitals with custom peer groups — Play Console Help.
  12. How we reduced our ANR by three times — OkCredit engineering.
  13. How to create a Google Play developer account — on the one-time $25 registration fee.
  14. Google Play 2026 fees: what your app actually pays — eCorpIT analysis of Play service fees.

Last updated: 4 August 2026.

Top comments (0)