A 96% crash-free rate sounds good. It is not — it means 1 in 25 sessions ends in a crash. Apps with crash-free rates below 99% see App Store ratings tank, users uninstall silently, and growth stalls. The fix is engineering work, not a vibe. This guide is the seven changes that move a typical unstable app from 96% to 99.5%+ crash-free.
The honest summary: mobile apps crash because of memory pressure, unhandled async errors, navigation edge cases, native-module mismatches, dependency bugs, and missing observability. Most of these are fixable in 2 to 4 weeks if you tackle them in the right order. Below is the order.
How to measure first
Install a crash reporting tool (Sentry, Firebase Crashlytics, Bugsnag, Datadog RUM) and let it run for at least 7 days before you change anything. Record the crash-free session rate, crash-free user rate, top 10 crash signatures by frequency, and which device classes / OS versions are affected. These are your before-state numbers. You will compare against them after each fix.
The number that matters most is **crash-free session rate**. Apple and Google both prioritise this in App Store / Play Store algorithms. Above 99.5% is considered healthy; below 98% triggers visible review drops and ranking impact. Most apps we audit start somewhere between 94% and 98%.
Fix 1 — Eliminate memory crashes (the biggest source)
On Android, OOM (out-of-memory) crashes are the largest single source of crashes for most apps — especially on low-RAM devices common in emerging markets. iOS handles memory differently but still kills apps that exceed limits. The symptoms: random crashes on image-heavy screens, crashes after long sessions, crashes mostly affecting older / cheaper devices.
The fix is usually about image handling. Three sub-fixes that resolve 80% of memory-driven crashes: (a) use a proper image library with caching and downsampling (FastImage on React Native, cached_network_image on Flutter, AsyncImage on SwiftUI), (b) resize images server-side or use signed URLs that return device-appropriate sizes, (c) explicitly clear image caches on memory warnings (Apple's didReceiveMemoryWarning, Android's onTrimMemory).
Audit your image-heavy screens specifically: feeds, galleries, product lists. Test on a low-end Android (2-3 GB RAM) before declaring this fixed.
Fix 2 — Catch every unhandled async error
Unhandled promise rejections in JavaScript / TypeScript code (React Native) and unawaited futures in Dart (Flutter) crash the app or leave it in undefined states. These are usually 20-30% of crashes by frequency.
The fix has three parts: wrap every async operation in a try / catch (or use Result-style return types), set up a global unhandled-rejection handler that logs to Sentry / Crashlytics, and use TypeScript strict mode (or Dart sound null safety) to catch missing await statements at compile time. For React Native specifically, enable Hermes's strict async tracking.
This is engineering hygiene, not a fancy fix. The teams that ship stable apps just do it consistently; the teams that ship crashy apps do not.
Fix 3 — Harden navigation
Navigation crashes happen at the seams: deep links pointing at screens that no longer exist, back-button navigation into invalid states, modal stack corruption when the user backgrounds the app mid-flow. Symptoms: crashes that happen right after the user taps a notification, right after they switch back from another app, or right after a specific screen transition.
The fix: validate every deep link before navigating to it, guard every navigation transition against the case where the target screen is unavailable, and use a navigation library with strong typed routes (React Navigation v6+ with typed params, GoRouter for Flutter). For deep-link-heavy apps, build a centralised deep-link handler that resolves URLs to typed navigation actions rather than scattered string-matching.
Fix 4 — Tame native modules
Native modules (the bridge between JS / Dart and native code) are a common crash source, especially after a React Native or Flutter version upgrade. Symptoms: crashes after a deploy, crashes on a specific device class, crashes in third-party SDK code you cannot inspect.
The fix is auditing your native module dependencies. List every native module the app uses. Check which ones have not been updated in 6+ months. Look at their GitHub issues for known crash reports. Replace abandoned modules with maintained alternatives. For modules you control, ensure they implement proper error boundaries on both the JS / Dart side and the native side, and that errors propagate cleanly across the bridge.
For React Native specifically, the New Architecture (Fabric, TurboModules) makes module crashes more deterministic. If you are still on the old bridge, migrating to the New Architecture is itself a crash-rate improvement.
Fix 5 — Manage dependencies
Outdated dependencies are a quiet crash source. Bugs that were fixed in newer versions still affect you. New OS versions sometimes break older library versions. Dependencies with abandoned maintenance accumulate vulnerabilities and incompatibilities.
The fix is dependency hygiene: weekly automated dependency-update PRs (Renovate, Dependabot), quarterly major-version-update sprints, and a “do not let dependencies fall more than two minor versions behind” rule. We have inherited many apps where 30%+ of crashes traced back to dependencies that had had their fixes shipped 6 to 12 months earlier.
Fix 6 — Add observability and alerting
You cannot fix what you do not see. Most teams have Sentry or Crashlytics installed but no one looks at it weekly, no alerts trigger when crash rate spikes, and no one tags releases so you can correlate crashes with deploys.
The fix: configure release tagging in your crash reporter so every crash report knows which version it came from. Set up Slack / email alerts that trigger when the daily crash-free rate drops below your target (e.g., below 99.4% triggers an alert). Make crash review part of someone's weekly responsibility — usually a senior mobile engineer or the mobile tech lead.
For serious apps, add session-replay tools (Sentry Session Replay, LogRocket, FullStory Mobile) so you can see what the user actually did before the crash. This pays back the cost on its own when you find the bug nobody could reproduce.
Fix 7 — Production-grade error boundaries
The last fix is wrapping every screen and every async operation in an error boundary that catches errors before they crash the app. In React Native: React Error Boundaries on every screen, fallback UI that shows a “something went wrong” message with a retry button. In Flutter: ErrorWidget and FlutterError.onError configured to log and recover. In native: graceful fallback handlers for every async network call.
The goal: errors should still happen (you cannot prevent network failures, OS bugs, race conditions), but they should be **handled** rather than **fatal**. A handled error shows the user “something went wrong, try again.” A fatal error closes the app and tanks your crash-free rate.
What good looks like after the seven fixes
Crash-free session rate above 99.5% across all device classes and OS versions.
Crash reports tagged by release so you can correlate spikes with deploys.
Alerting in place for crash-rate regressions before users notice.
No top-10 crash signature contributing more than 0.05% of sessions.
Low-end Android performance verified on devices with 2-3 GB RAM (real devices, not simulators).
These are the targets we hold every mobile build to. App stores notice the difference; users feel it; retention reflects it.
Common questions
What’s a healthy crash-free rate for a production app?
Above 99.5% is the bar for healthy. Above 99.8% is excellent. Below 99% triggers visible negative impact on App Store and Play Store rankings, drives review-score drops, and increases uninstall rates. The industry average across all apps is somewhere around 98% to 99% — meaning most apps have a real opportunity to improve. The seven fixes in this article are what we apply to move apps from average to top-tier.
How much will fixing all seven things improve crash-free rate?
On a typical unstable app (94 to 97% crash-free), all seven fixes together usually move crash-free rate above 99.5%. Specific gains depend on starting state: image-heavy apps see the largest gains from the memory fix; apps with heavy native module use see the largest gains from auditing modules; apps with poor async hygiene see the largest gains from error boundaries and unhandled-rejection handlers. Most engagements take 2 to 4 weeks of focused engineering time.
How do I test mobile crashes that only happen on certain devices?
Real-device testing on a service like BrowserStack App Live or AWS Device Farm. Test specifically on low-end Android devices (2-3 GB RAM, older OS versions) where most memory-driven crashes manifest. Use crash reports filtered by device class to identify which specific devices are affected. For really stubborn crashes that only happen on specific devices, ship a debug build to a few users on those devices and capture logs in production. Simulator-only testing misses a significant fraction of real-world crashes.
Will Sentry / Crashlytics catch all crashes?
No, but they catch most. Native crashes that happen before the SDK initialises are missed. Out-of-memory kills on Android are tricky — Crashlytics catches most, Sentry sometimes does not. ANRs (App Not Responding) are detected by Crashlytics on Android but require extra configuration on iOS. We typically install both Sentry (for JS / Dart-level errors and good correlation tools) and Crashlytics (for the native-level crash detection Sentry can miss). Belt and braces.
Does a stable mobile app actually affect downloads and retention?
Yes, dramatically. App Store and Google Play both factor crash-free rate into ranking algorithms. Crash-impacted users are 30 to 60% more likely to uninstall within a week. Reviews tank when crashes are visible: a single “keeps crashing” 1-star review costs significantly more long-term traffic than a 5-star review provides. We have measured 15 to 35% download lift and 20 to 40% retention lift in the first 90 days after crash-rate work on apps that started below 98%.
Want a free mobile crash audit?
Send us your App Store / Play Store link and crash reporter access. We will send back a 2-page audit showing your current crash-free rate, the top 10 crash signatures, and the seven highest-impact fixes for your app.