惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
Jina AI
Jina AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
Netflix TechBlog - Medium
B
Blog RSS Feed
Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
The Blog of Author Tim Ferriss
D
Docker
博客园 - 聂微东
博客园 - 【当耐特】
博客园 - 三生石上(FineUI控件)
L
LangChain Blog
量子位
宝玉的分享
宝玉的分享
博客园 - 司徒正美
The Cloudflare Blog
G
Google Developers Blog
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Android Enterprise App Performance Benchmarks: What US CT...
Mohammed Ali · 2026-04-26 · via DEV Community

Google considers apps with crash rates above 1.09% or ANR rates above 0.47% as bad behavior and may reduce their Play Store visibility. These are the public benchmarks Google uses to evaluate app quality. Your vendor should be able to show you their numbers against both thresholds.

Key findings
Google marks apps with crash rates above 1.09% or ANR rates above 0.47% as bad behavior, reducing Play Store visibility. These are the thresholds your vendor must beat.
Android cold start is slower than iOS due to JVM warmup. The target for mid-range Android hardware is under 2.5 seconds. Measuring on flagship devices only produces misleading results.
60% of the US enterprise Android fleet is mid-range Samsung A-series and Motorola G-series devices. Performance benchmarks must be validated on these devices, not just on flagship hardware.
Wednesday targets 99.5% crash-free and sub-0.3% ANR rate across the full 16-device Android matrix. The fashion e-commerce case study maintained 99% crash-free at 20 million users.

The Android Vitals framework

Android Vitals is Google's public framework for measuring Android app quality. The Play Console exposes these metrics for every app in production. They are the numbers Google uses when deciding how much Play Store visibility to give your app.

Four core metrics:

Crash rate: the percentage of daily active users who experience at least one crash. Threshold: 1.09%. Apps above this are marked bad behavior.

ANR rate: the percentage of daily active users who experience at least one ANR (Application Not Responding). Threshold: 0.47%. Apps above this are marked bad behavior.

Excessive wakeups: the percentage of battery sessions where the app wakes the device more than 10 times per hour while on battery. Affects battery life and user satisfaction.

Stuck partial wake locks: the percentage of battery sessions where the app holds a partial wake lock for more than one hour continuously. Indicates background processing that is holding the device awake unnecessarily.

The crash rate and ANR rate thresholds are the ones that matter most for enterprise buyers. They directly affect whether users can complete their work. A crash rate above 1.09% means more than 1 in 100 daily users encounters a crash. An ANR rate above 0.47% means nearly 1 in 200 users sees the "App is not responding" dialog every day.

Your vendor should be able to show you their clients' Android Vitals data. If they cannot, or will not, that is an answer.

Crash-free rate: the primary metric

Crash-free rate is the inverse of crash rate: the percentage of sessions where the app does not crash. A 1.09% crash rate translates to 98.91% crash-free — the floor Google's algorithm penalizes below.

Enterprise vendors should target 99.5% crash-free on Android. This is lower than the 99.7% target achievable on iOS, for a specific reason: Android device fragmentation means the same app runs on more hardware and OS configurations, introducing more vectors for device-specific crashes that a complete test matrix cannot predict.

The gap between 99.5% and 99.7% is not negligible. At 99.5% crash-free, 5 in 1,000 user sessions end in a crash. At 99.7%, 3 in 1,000 do. For an app with 10,000 daily active users, that is 50 crashed sessions per day vs 30. For an enterprise field operations app, those are 50 workers per day who lost their work and had to restart.

The crash-free rate is measured in Firebase Crashlytics or Google's own Play Console crash reporting. Self-reported crash numbers from vendors are not the same. Crashlytics captures crashes that happen in the field, on devices the team has never tested, in usage patterns the team did not anticipate. The production crash rate is always higher than the development crash rate.

Ask your vendor for a Crashlytics screenshot or export from a current client engagement. Six months of crash-free trend data tells you more than a claimed percentage.

The causes of crash rate failure above 99.5%:

  • Incomplete device matrix. Crashes that only appear on specific hardware or OS versions are missed.
  • Memory management issues. Apps that exceed device memory limits are killed, which appears as a crash in Crashlytics.
  • Unhandled exceptions in background coroutines. Kotlin coroutine exceptions that are not caught crash the app when they reach the top of the coroutine scope.
  • Third-party SDK crashes. SDKs update independently. An SDK update between releases can introduce crashes that the app itself is not responsible for, but that appear in the app's crash metrics.

ANR rate: the hidden performance problem

ANRs are the less-discussed Android quality metric, but they are as important as crashes for enterprise apps.

An ANR occurs when the Android main thread is blocked for more than 5 seconds. The OS shows a dialog: "App is not responding. Do you want to close it or wait?" Most users tap Close. The session ends. The work is lost.

ANRs differ from crashes in an important way: they are preventable through architecture decisions, not through bug fixing. The root cause of most ANRs is one of a small set of patterns:

Main thread I/O: network requests or database queries executed on the main thread. The main thread is blocked waiting for the I/O to complete. The fix is dispatching I/O to Dispatchers.IO in a coroutine.

Deadlocks: two threads waiting for each other. Most Android deadlocks involve the main thread holding a lock that a background thread also needs. The fix requires removing the lock or restructuring the concurrency model.

Heavy initialization in Application.onCreate: complex dependency graphs, large file reads, or synchronous network calls in the Application class block the main thread during app startup. The fix is deferred initialization using the App Startup library or lazy initialization patterns.

Synchronous main thread operations: any blocking call on the main thread. This includes Thread.sleep() (which is never appropriate on the main thread), synchronized blocks that can block indefinitely, and callback-based APIs that call back on the main thread with heavy computation.

Google's 0.47% ANR threshold is the play store bad behavior line. Wednesday targets sub-0.3% ANR rate. The tighter target provides margin for production surprises and keeps the app well clear of Google's threshold.

Cold start time on mid-range devices

Cold start is the time from when the user taps the app icon to when the first frame of the app is drawn. On Android, this is slower than iOS by design.

iOS apps launch from a native binary. Android apps launch from a JVM process that must be created, the Dex bytecode must be loaded, and the Application class must be initialized. This additional setup takes time. On the same generation of hardware, an Android cold start is typically 30-50% longer than an equivalent iOS cold start.

The target for enterprise Android apps on mid-range hardware is cold start under 2.5 seconds. On flagship hardware (Pixel 8, Galaxy S24), this is achievable without significant optimization. On mid-range hardware (Galaxy A34, Moto G73) — which represents 60% of the US enterprise Android fleet — cold start times are 40-60% longer than flagship.

This matters because developers test on their development hardware, which is typically flagship. An app that starts in 1.5 seconds on a Pixel 8 may take 2.8 seconds on a Galaxy A34. If no one measured on a Galaxy A34 before launch, the field team's experience is not what the developer saw.

The optimization levers are: reducing Application.onCreate work, using App Startup for lazy dependency initialization, reducing the number of classes loaded during startup, and using background thread initialization for non-critical startup paths. Jetpack Compose's modern rendering pipeline also reduces first-frame rendering time compared to XML-based View systems.

Wednesday measures cold start on mid-range devices. The CI matrix includes Galaxy A-series hardware specifically for startup time monitoring.

Scroll performance: 60fps on mid-range

60 frames per second is the human visual threshold for smooth motion. On Android, hitting 60fps in a scrolling list requires rendering each frame in under 16 milliseconds.

Mid-range Android devices have slower GPUs than flagship devices. An animation or list that renders at 60fps on a Pixel 8 may drop to 40fps on a Galaxy A34. Users notice. A janky scrolling list in a field operations app increases cognitive load and slows work completion.

The causes of scroll performance problems in Jetpack Compose:

Recomposition on every frame: state reads inside composables that change every frame (animation progress, scroll position) cause the composable to recompose every frame. Use derivedStateOf to read animated values inside composables, which prevents full recomposition during animation.

Heavy computables in item factory: LazyColumn item content that performs complex computation on every item render. Use remember to cache computations that depend on stable inputs.

Non-optimized image loading: images loaded without a proper caching layer decode on the main thread. Use Coil or Glide with appropriate size constraints and disk caching for all image loading in scrollable lists.

Overdraw: composables that draw multiple layers on top of each other, each requiring a separate GPU pass. Reduce overdraw by simplifying the composable hierarchy and avoiding unnecessary background draws.

Wednesday runs scroll performance benchmarking using Jetpack Compose's Macrobenchmark library on mid-range physical devices. The 60fps target is measured on Galaxy A-series hardware, not just on the development team's flagship devices.

Memory and battery benchmarks

Memory: enterprise Android apps should stay under 200MB of RAM during typical use. Apps exceeding 300MB on devices with 3-4GB of RAM are candidates for low-memory killing, which appears in Crashlytics as a crash.

Memory profiling is part of Wednesday's pre-release review. Common issues — bitmap caches without size bounds, unreleased ViewModel references, Compose state that accumulates over navigation — are caught before they reach production.

Battery: apps should not appear in the device's battery usage statistics under normal use. Users who see the app listed as a significant battery consumer will disable it or uninstall it. The Google Play Vitals excessive wakeups threshold (more than 10 wakeups per hour while on battery) is the line to stay under.

Field operations apps that require background location or background sync are legitimate high battery consumers. The goal is not to minimize battery use at the expense of functionality. The goal is to use the correct platform APIs — WorkManager constraints, ForegroundService with appropriate importance level — so the Android OS treats the app's battery use as intentional rather than as a bug.

Read more case studies at mobile.wednesday.is/work

How to measure all of this

The tools for each metric:

Crash-free rate: Firebase Crashlytics or Google Play Console crash reporting. Crashlytics provides session-level data with device and OS breakdown. The Play Console provides the official Android Vitals data Google uses for its algorithm.

ANR rate: Android Vitals in the Play Console. ANR traces are available for analysis in the Play Console — each ANR includes the thread state at the time of the ANR, which reveals the root cause. Firebase Crashlytics also captures ANR data.

Cold start time: Jetpack Compose Macrobenchmark library for synthetic benchmarks. Android Vitals in the Play Console provides real-world startup time data from production users. The production data is more valuable than synthetic benchmarks.

Scroll performance: Macrobenchmark for controlled measurements. Android Studio's Compose Visual Profiler shows recomposition counts per composable. Google Play Vitals tracks frozen frame rate and slow rendering rate across the production user base.

Memory: Android Studio Memory Profiler for development analysis. LeakCanary for detecting reference leaks in development builds. Android Vitals tracks memory usage anomalies in production.

Battery: Android Studio Energy Profiler for development. Android Vitals tracks wakeup counts and wake lock durations in production.

Wednesday's Android performance benchmarks

Wednesday targets 99.5% crash-free and sub-0.3% ANR rate across the full 16-device Android matrix. Cold start under 2.5 seconds on mid-range hardware. Scroll performance at 60fps on Galaxy A-series devices in standard list views.

The fashion e-commerce case study is the scale reference: 99% crash-free maintained at 20 million users across every release over three years. The Android app ships weekly. The 20M user base includes a diverse Android device fleet — the performance benchmarks hold at that scale.

Wednesday delivers monthly performance reports for every active Android engagement. The report covers crash-free trend, ANR rate trend, top crash signatures, and Play Store review status. The numbers are pulled directly from Firebase Crashlytics and the Play Console, not self-reported.

Ask your current vendor for the same. If they cannot produce a Crashlytics export and Play Vitals data, the performance benchmarks they are quoting are not measured.


Originally published at https://mobile.wednesday.is/writing/android-enterprise-app-performance-benchmarks-2026