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

推荐订阅源

爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Security Blog
Microsoft Security Blog
IT之家
IT之家
M
MIT News - Artificial intelligence
S
SegmentFault 最新的问题
H
Hackread – Cybersecurity News, Data Breaches, AI and More
AI
AI
I
InfoQ
博客园_首页
T
Threatpost
Know Your Adversary
Know Your Adversary
T
Tenable Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
NISL@THU
NISL@THU
V
Vulnerabilities – Threatpost
The Hacker News
The Hacker News
N
News and Events Feed by Topic
O
OpenAI News
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
TaoSecurity Blog
TaoSecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Spread Privacy
Spread Privacy
W
WeLiveSecurity
Hacker News - Newest:
Hacker News - Newest: "LLM"
K
Kaspersky official blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Troy Hunt's Blog
Help Net Security
Help Net Security
Hacker News: Ask HN
Hacker News: Ask HN
C
CERT Recently Published Vulnerability Notes
H
Heimdal Security Blog
A
About on SuperTechFans
The Last Watchdog
The Last Watchdog
腾讯CDC
Jina AI
Jina AI
Schneier on Security
Schneier on Security
T
Threat Research - Cisco Blogs
Security Latest
Security Latest
Recorded Future
Recorded Future
量子位
有赞技术团队
有赞技术团队
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org

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 Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Android Enterprise App Performance Benchmarks: What US CTOs Should Expect From Vendors in 2026
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