# Mobile App Monitoring: Crashes, ANRs, and Performance

> Debug crashes, ANRs, and performance issues across iOS, Android, React Native, and Flutter. Get stack traces, session replays, and suspect commits with every issue

**URL:** https://sentry.io/solutions/mobile-developers/

---

Don’t wait for your users to let you know about issues. Sentry’s mobile app monitoring - for crashes, errors, and performance issues - helps you get the context needed to diagnose and debug faster.

## Supported SDKs

- iOS — [Docs](https://docs.sentry.io/platforms/apple/guides/ios/)

- Flutter — [Docs](https://docs.sentry.io/platforms/dart/guides/flutter/)

- Android — [Docs](https://docs.sentry.io/platforms/android/)

- React Native

- Unity — [Docs](https://sentry.io/for/unity/)

- .NET MAUI

## Details

### Catch and fix mobile issues faster

#### Debug errors, crashes, ANRs, and app hangs faster

Crashes, ANRs, app hangs, and unexpected app behavior are inevitable—but spending hours trying to reproduce them shouldn’t be. Sentry links context like stack traces, device and app state, and user actions to help you go from alert to root cause—no log diving or waiting on user reports required.

#### Get alerts and full context behind mobile issues

It’s not fun to have to investigate problems like  hydration errors, but it’s worse when you don’t know about them in the first place. 

Sentry groups errors automatically, sends alerts, and gives you context like: 

Stack traces

Breadcrumbs

Device/OS details

Suspect commits

so you can identify the issue owners, triage, and find the root cause faster.

#### Debug device-specific issues (without owning every mobile device)

A checkout experience breaks on an ancient Android device with one specific OS version, but not others. 

Instead of having to reproduce the issue yourself, use [Session Replay](https://sentry.io/product/session-replay/) to get a video-like recreation of what users saw and did leading up to an error on the exact device and OS version.

#### Automatically connect mobile errors to owners and commits

When your mobile app gets vague user reports about freezing but there’s no clear repro steps, and the only clue is an uptick in ANRs, you’re usually in for a slog of a bug hunt.

Sentry cuts through the ambiguity by identifying the exact commit and author likely responsible for introducing the issue. Instead of wading through recent merges or pinging five different teammates, you get a direct path to the root cause and a faster fix.

### Spot issues early, fix them automatically

#### See mobile jank and errors before hearing about them in user reviews

Making releases successful and ensuring the long-term stability of your app requires visibility into more than just errors.

Sentry helps you monitor releases, critical workflows, and overall app health, so you can catch stuttery screen transitions, layout shifts, and slow touch responsiveness before users churn or leave negative reviews.

#### Know when releases go sideways before you lose users

Releases shouldn’t be a waiting game to find out from your users that search filters are broken on iOS.

Use Sentry to monitor crash-free sessions, release adoption, and stability trends the moment a new version goes live.

You’ll also see new issues tied to each release—so you can fix fast or roll back if needed.

#### See mobile metrics like TTID/TTFD and crash rates at a glance

Your users know exactly how long it takes to load the checkout screen—and you should too.

Sentry automatically captures key performance and stability metrics, so you can track things like crash rates, TTID & TTFD, screen rendering time, network request, and transactions per minute.  Drill into specific screens and user flows to understand and optimize experience where they matter most.

#### Go from issues to code fixes automatically with AI debugging

Not sure what’s at fault when your mobile app keeps freezing as users add a second item to their cart? 

Seer, Sentry’s AI agent, identifies the root cause of problems with 94.5% accuracy, generates code fixes and can create pull requests in GitHub to resolve issues faster.

It’s AI that can fix everything from enterprise platforms to your vibe-coded pizza delivery app.

### Eliminate mobile jank and lag

#### Fix mobile jank and laggy code faster

Knowing your checkout flow is slow is one thing—pinpointing why is harder, and it pulls time and focus away from building new features.

Sentry gives you end-to-end visibility into the request lifecycle, from the user’s first tap in the mobile app to the final response from your backend, so you can find and fix performance bottlenecks faster.

#### See the exact code breaking your key experiences

Fixing slow load times or a janky nav bar shouldn’t be a guessing game.

With Sentry, you get a real-time breakdown of requests and operations as they happen in your mobile app.

Pinpoint the exact slow API call or lagging database query behind the issue to improve performance and the user experience.

#### Find the function calls killing your mobile UX

On mobile, even 50ms of delay on a button tap can be the difference between smooth and sluggish.

Sentry captures code execution from real user sessions, helping you identify what’s slowing down responsiveness right down to the function level.

Visualize call stacks across every thread during execution to spot bottlenecks and deliver a faster, smoother mobile app experience.

#### See logs right alongside your issues, traces, and session replays

Sentry connects structured logs to where you’re already debugging, so you can see exactly what happened and why. Uncover hidden state bugs, prioritize fixes based on impact, and add more context to every investigation.

## Cookbook recipes

### Debug undefined properties in React Native with Sentry Logs

Use Sentry Logs in React Native and your backend to debug undefined properties, pinpoint timing bugs vs data issues, and verify your fix.

### Track and fix checkout performance in React Native with Sentry tracing

Use Sentry tracing to instrument a React Native checkout flow with a Python backend, identify slow HTTP requests, and set up alerts and dashboards.

## Customer Story

> If our app is slow, users won’t wait—they’ll just leave. Using Sentry to debug and monitor performance is a key factor to our success in keeping users in our app and engaged.

[Read the full story](https://sentry.io/customers/flo/)

- **50%** faster key transactions

- **99.9%** crash-free sessions across millions

- **50+** backend deploys/day

## More resources for mobile developers

- [Sentry vs. Crashlytics: The Mobile Developer's Decision-Making Guide](https://sentry.io/resources/sentry-vs-crashlytics-mobile-developers-guide/): Many mobile developers weigh the differences between Firebase Crashlytics and Sentry when they are trying to choose the right crash, error, and performance moni

- [Improve React Native Performance using Tracing and Logs](https://sentry.io/resources/react-native-workshop/): ​In this hands-on workshop, we’ll show you how to connect the dots between slowdowns, crashes, and the user experience in your React Native app

- [Unsnag Your Mobile Monitoring: Why Teams Are Switching to Sentry](https://sentry.io/resources/unsnag-your-mobile-monitoring/): Mobile error monitoring tools shouldn’t flood your inbox or leave you numb to alerts—just surface what actually matters. Most mobile monitoring tools give you j

- [Introducing Session Health in Sentry (Open Beta)](https://blog.sentry.io/introducing-session-health-in-sentry-now-in-open-beta/): Session Health gives you a clear view of stability and user experience—and lets you drill into each dip, with the connected issues that might be causing it, so you can push a quick fix or keep rolling out with confidence.

## Sentry vs Firebase Crashlytics

### SDK Coverage

- **Sentry**: Android, iOS, React Native, Flutter, .NET MAUI, Kotlin Multiplatform, Cordova, Capacitor, Unity, Unreal

- **Firebase Crashlytics**: Android, iOS, Flutter, Unity

### Context and Insights

- **Sentry**: Offers metadata, stack traces, breadcrumbs, suspect commits, screenshots, session replay, view hierarchy

- **Firebase Crashlytics**: Offers metadata, stack traces, keys, logs

- **Sentry**: Source Map support for React Native

- **Firebase Crashlytics**: No Source Map support for React Native

- **Sentry**: Search and filter by custom tags; View trends and analyze data with Dashboards and Discover

- **Firebase Crashlytics**: Limited search and filter capabilities; Export and analyze data in BigQuery

### Workflow

- **Sentry**: Fully customizable alerts

- **Firebase Crashlytics**: Pre-set alerts

- **Sentry**: Automatic issue assignment and notifications

- **Firebase Crashlytics**: No issue assignment or targeted notifications

- **Sentry**: Two-way data flow between other tools

- **Firebase Crashlytics**: One-way data flow to other tools

### Innovation & Scale

- **Sentry**: Product investments focused on enabling developers to adopt new technologies

- **Firebase Crashlytics**: Product investments focused on deeper integration with Firebase Platform

- **Sentry**: Vendor agnostic

- **Firebase Crashlytics**: Reliant on Firebase Platform

- **Sentry**: EU Data residency

- **Firebase Crashlytics**: Not GDPR compliant

## Quick Start

### Python

Install the Sentry Python SDK with pip

```bash
pip install sentry-sdk
```

Configuration should happen as early as possible in your application's lifecycle.

```python
import sentry_sdk

sentry_sdk.init(
  dsn="https://examplePublicKey@o0.ingest.sentry.io/0",
  # Add data like request headers and IP for users, if applicable;
  # see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
  send_default_pii=True,
  # Set traces_sample_rate to 1.0 to capture 100%
  # of transactions for tracing.
  traces_sample_rate=1.0,
  #Enable logs to be sent to Sentry
  enable_logs=True,
  # To collect profiles for all profile sessions,
  # set profile_session_sample_rate to 1.0.
  profile_session_sample_rate=1.0,
  # Profiles will be automatically collected while
  # there is an active span.
  profile_lifecycle="trace",
)
```

### JavaScript

Install the Sentry JavaScript SDK with npm

```bash
npm install @sentry/browser --save
```

Configuration should happen as early as possible in your application's lifecycle.

```javascript
import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  // Adds request headers and IP for users, for more info visit:
  // https://docs.sentry.io/platforms/javascript/configuration/options/#sendDefaultPii
  sendDefaultPii: true,
  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for tracing.
  tracesSampleRate: 1.0,
  // Set tracePropagationTargets to control for which URLs trace propagation should be enabled
  tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
  // Enable logs to be sent to Sentry
  enableLogs: true,
  // Set profilesSampleRate to 1.0 to profile every transaction.
  // Since profilesSampleRate is relative to tracesSampleRate,
  // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate
  // For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would
  // result in 25% of transactions being profiled (0.5*0.5=0.25)
  profilesSampleRate: 1.0,
  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.browserProfilingIntegration(),
  ],
});
```

### React

Run the command for your preferred package manager to add the Sentry SDK to your application:

```bash
npm install @sentry/react --save
```

To import and initialize Sentry, create a file in your project's root directory, for example, `instrument.js`, and add the following code:

```javascript
import * as Sentry from "@sentry/react";

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  // Adds request headers and IP for users, for more info visit:
  // https://docs.sentry.io/platforms/javascript/guides/react/configuration/options/#sendDefaultPii
  sendDefaultPii: true,
  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for tracing.
  // Learn more at
  // https://docs.sentry.io/platforms/javascript/configuration/options/#traces-sample-rate
  tracesSampleRate: 1.0,
  // Set `tracePropagationTargets` to control for which URLs trace propagation should be enabled
  tracePropagationTargets: [/^//, /^https://yourserver.io/api/],
  // Enable logs to be sent to Sentry
  enableLogs: true,
  // Set profilesSampleRate to 1.0 to profile every transaction.
  // Since profilesSampleRate is relative to tracesSampleRate,
  // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate
  // For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would
  // result in 25% of transactions being profiled (0.5*0.5=0.25)
  profilesSampleRate: 1.0,
  integrations: [
    // If you're using react router, use the integration for your react router version instead.
    // Learn more at
    // https://docs.sentry.io/platforms/javascript/guides/react/features/react-router/
    Sentry.browserTracingIntegration(),
    Sentry.browserProfilingIntegration(),
  ],
});
```

Initialize Sentry as early as possible in your application. We recommend putting the import of your initialization code as the first import in your app's entry point:

```javascript
// Sentry initialization should be imported first!
import "./instrument";
import App from "./App";
import { createRoot } from "react-dom/client";

const container = document.getElementById("app");
const root = createRoot(container);
root.render(<App />);
```

To make sure Sentry captures all your app's errors, configure error handling based on your React version. 
 For React versions 19 and up:  

```javascript
import { createRoot } from "react-dom/client";
import * as Sentry from '@sentry/react';

const container = document.getElementById("app");
const root = createRoot(container, {
  // Callback called when an error is thrown and not caught by an ErrorBoundary.
  onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
    console.warn('Uncaught error', error, errorInfo.componentStack);
  }),
  // Callback called when React catches an error in an ErrorBoundary.
  onCaughtError: Sentry.reactErrorHandler(),
  // Callback called when React automatically recovers from errors.
  onRecoverableError: Sentry.reactErrorHandler(),
});
root.render();
```

For React versions 18 and below, use the ErrorBoundary component to automatically send errors from specific component trees to Sentry and provide a fallback UI:

```javascript
import React from "react";
import * as Sentry from "@sentry/react";

<Sentry.ErrorBoundary fallback={<p>An error has occurred</p>}>
  <Example />
</Sentry.ErrorBoundary>;
```

### Next.js

To install Sentry using the installation wizard, run thrun the following command and step through the prompts:

```bash
npx @sentry/wizard@latest -i nextjs
```

For manual installation run the following command and use the following configurations:

```bash
npm install @sentry/nextjs --save
```

Extend your app's default Next.js options by adding code with `withSentryConfig` into your `next.config.(js|mjs)` file:

```javascript
const { withSentryConfig } = require("@sentry/nextjs");
const nextConfig = {
  // Your existing Next.js configuration
};
// Make sure adding Sentry options is the last code to run before exporting
module.exports = withSentryConfig(nextConfig, {
  org: "example-org",
  project: "example-project",
  // Only print logs for uploading source maps in CI
  // Set to `true` to suppress logs
  silent: !process.env.CI,
  // Automatically tree-shake Sentry logger statements to reduce bundle size
  disableLogger: true,
});
```

#### Client-Side Configuration

```javascript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  // Adds request headers and IP for users, for more info visit:
  // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii
  sendDefaultPii: true,
  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for tracing.
  // We recommend adjusting this value in production
  // Learn more at
  // https://docs.sentry.io/platforms/javascript/configuration/options/#traces-sample-rate
  tracesSampleRate: 1.0,
  // Enable logs to be sent to Sentry
  enableLogs: true,
  // Set profilesSampleRate to 1.0 to profile every transaction.
  // Since profilesSampleRate is relative to tracesSampleRate,
  // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate
  // For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would
  // result in 25% of transactions being profiled (0.5*0.5=0.25)
  profilesSampleRate: 1.0,
});

// This export will instrument router navigations, and is only relevant if you enable tracing.
// `captureRouterTransitionStart` is available from SDK version 9.12.0 onwards
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
```

#### Server-Side Configuration

```javascript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  // Adds request headers and IP for users, for more info visit:
  // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii
  sendDefaultPii: true,
  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for tracing.
  // We recommend adjusting this value in production
  // Learn more at
  // https://docs.sentry.io/platforms/javascript/configuration/options/#traces-sample-rate
  tracesSampleRate: 1.0,
  // Enable logs to be sent to Sentry
  enableLogs: true,
});
```

#### Register Sentry Server-Side SDK Initialization

Create a Next.js Instrumentation file named `instrumentation.(js|ts)` in your project root or inside the `src` folder if you have one. Import your server and edge configurations, making sure that the imports point to your specific files:

```javascript
export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    await import("./sentry.server.config");
  }
  if (process.env.NEXT_RUNTIME === "edge") {
    await import("./sentry.edge.config");
  }
}
```

### Go

Grab the Sentry Go SDK:

```bash
go get "github.com/getsentry/sentry-go"
```

Configuration should happen as early as possible in your application's lifecycle.

```text
err := sentry.Init(sentry.ClientOptions{
  Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  // Enable printing of SDK debug messages.
  // Useful when getting started or trying to figure something out.
  Debug: true,
  // Adds request headers and IP for users,
  // visit: https://docs.sentry.io/platforms/go/data-management/data-collected/ for more info
  SendDefaultPII: true,
  EnableTracing: true,
  // Set TracesSampleRate to 1.0 to capture 100%
  // of transactions for tracing.
  TracesSampleRate: 1.0,
})
if err != nil {
  log.Fatalf("sentry.Init: %s", err)
}
// Flush buffered events before the program terminates.
// Set the timeout to the maximum duration the program can afford to wait.
defer sentry.Flush(2 * time.Second)
```

### Ruby

Add the sentry-ruby gem to your Gemfile:

```ruby
gem "sentry-ruby"
```

Configuration should happen as early as possible in your application's lifecycle.

```ruby
require 'sentry-ruby'

Sentry.init do |config|
  config.dsn = 'https://examplePublicKey@o0.ingest.sentry.io/0'

  # get breadcrumbs from logs
  config.breadcrumbs_logger = [:sentry_logger, :http_logger]

  # Add data like request headers and IP for users, if applicable;
  # see https://docs.sentry.io/platforms/ruby/data-management/data-collected/ for more info
  config.send_default_pii = true
  # enable tracing
  # we recommend adjusting this value in production
  config.traces_sample_rate = 1.0
  # Enable logs to be sent to Sentry
  config.enable_logs = true
  # enable profiling
  # this is relative to traces_sample_rate
  config.profiles_sample_rate = 1.0
end
```

### PHP

Install the Sentry SDK using Composer:

```bash
composer require sentry/sentry
```

To use Profiling, you'll also need to install the Excimer extension via PECL:

```bash
pecl install excimer
```

To capture all errors, even the one during the startup of your application, you should initialize the Sentry PHP SDK as soon as possible.

```php
\Sentry\init([
  'dsn' => 'https://examplePublicKey@o0.ingest.sentry.io/0',
  // Add request headers, cookies and IP address,
  // see https://docs.sentry.io/platforms/php/data-management/data-collected/ for more info
  'send_default_pii' => true,
  // Specify a fixed sample rate
  'traces_sample_rate' => 1.0,
  // Enable logs to be sent to Sentry
  'enable_logs' => true,
  // Set a sampling rate for profiling - this is relative to traces_sample_rate
  'profiles_sample_rate' => 1.0,
]);
```

### .NET

Install the NuGet package to add the Sentry dependency:

```shell
dotnet add package Sentry -v 5.16.2
```

To use Profiling, you'll also need to install the Sentry.Profiling package:

```shell
dotnet add package Sentry.Profiling -v 5.16.2
```

To capture all errors, even the one during the startup of your application, you should initialize the Sentry .NET SDK as soon as possible.

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://examplePublicKey@o0.ingest.sentry.io/0";
    options.Debug = true;
    // Adds request URL and headers, IP and name for users, etc.
    options.SendDefaultPii = true;
    // A fixed sample rate of 1.0 - 100% of all transactions are getting sent
    options.TracesSampleRate = 1.0f;
    // A sample rate for profiling - this is relative to TracesSampleRate
    options.ProfilesSampleRate = 1.0f;
});
```

---

*Source: [sentry.io/solutions/mobile-developers/](https://sentry.io/solutions/mobile-developers/)*
