---
url: 'https://www.corbado.com/blog/native-app-authentication-analytics'
title: 'Native App Authentication Analytics: what to track'
description: 'Native app authentication analytics: why the login funnel misses 80% of app users, the 6 KPIs to track instead and the signals only an app SDK can collect.'
lang: 'en'
author: 'Vincent Delitz'
date: '2026-08-12T13:43:54.768Z'
lastModified: '2026-08-12T16:07:06.658Z'
keywords: 'native app authentication analytics, mobile app login analytics, native app passkey analytics, app authentication observability, unexpected logout rate'
category: 'Passkeys Strategy'
---

# Native App Authentication Analytics: what to track

## 1. Introduction

A team that has instrumented its web login knows the shape of that problem by heart.
Visitors arrive, some start a login, fewer finish it and the work is to find the steps
where people fall out. That model produced a decade of tooling and it works.

Then the same team points it at the native app and the numbers stop making sense. Login
volume is far lower, because a login in an app happens roughly once per install rather
than once per visit. Only new installs, guests and users who lost their session ever reach
a login screen, so the funnel that dominates every web dashboard covers a minority of app
sessions. And the number that decides whether the app earns its keep, whether a user is
still logged in six months after installing, appears nowhere at all.

Adding more instrumentation does not fix this. The question itself is a different one. On
the web the goal is to turn a visitor into an account and a completed login. In an app
that win is already paid for: somebody bought the install with an app store campaign, a
banner or a checkout interstitial, and it happens once. From there the job is to keep an
authenticated state alive that ideally never breaks again.

This article sets out what native app authentication analytics has to measure instead:
which KPIs are worth defining, which signals only exist inside an app and what an SDK that
collects them is allowed to do on a platform where a crash rate is a distribution problem.

## Key Facts

- In large consumer apps, **75% to 85% of app users are already authenticated** when they
  open the app, so the login funnel covers a minority of sessions.
- Native authentication analytics has **two objects**, not one: the login flow (new installs,
  guests, logged-out users) and the authentication state (everybody else).
- **Unexpected logouts are the native equivalent of a failed login** and they are rarely
  measured, which is why "we are not sure why users get logged out" is such a common
  sentence in app teams.
- **Passkeys survive a reinstall, app sessions usually do not.** The platform credential
  manager keeps the credential, the app sandbox that held the token is wiped.
- An app SDK works under constraints a web tag never had: Google Play treats a
  user-perceived crash rate of **1.09%** and an **ANR** rate of **0.47%** as bad behavior
  thresholds that cost you discoverability. ANR stands for application not responding, the
  frozen-UI counterpart to a crash.

## 2. Why App Authentication is not a Funnel Problem

### 2.1 Install is the expensive Win

Web authentication analytics inherited its worldview from e-commerce. Traffic is
anonymous by default, every session is a fresh chance to convert and the login is a gate
standing between a visitor and the thing they came for. Measuring that gate is obviously
worth it, and the [login conversion rate](https://www.corbado.com/kpi/login-conversion-rate) is the number that
falls out of it.

An app inverts every one of those assumptions. Traffic arrives installed rather than
anonymous. The acquisition cost was paid before the first screen rendered. And the login
is a one-time setup step that the operating system, the credential manager and your own
token storage then conspire to never show again.

That is the entire point of an app. In many large consumer apps, 75% to 85% of app users
are already authenticated when they open it. A login funnel measured on that population
describes the exception rather than the rule.

Put the two shapes next to each other and they barely belong on the same diagram.

### 2.2 Session Funnel vs User Funnel

The practical consequence shows up as a mismatch between two ways of counting. The two
definitions differ only in what sits in the denominator, and that one difference decides
which drop-offs you can see at all.

A **session funnel** asks: of the sessions that started a login, how many finished it? That
is the right question on the web, where a session roughly equals a visit and a visit
roughly equals an opportunity.

A **user funnel** asks: of the people who installed, how many reached an authenticated
state, and how many are still in it? That is the right question in an app, where one login
is meant to serve hundreds of later sessions.

Run both against the same app and they disagree sharply, as the diagram below shows. A
session funnel that reports 90% completion tells you very little, because it was computed
over the small share of sessions that contained a login at all. A user funnel can show
that a meaningful part of the install base fell out of the authenticated state months ago,
and nothing in the session view would ever surface it.

### 2.3 Blind Spot at the Web-to-App Boundary

There is a second effect, and it corrupts the web numbers rather than the app numbers.

Some users abandon a web login not because it failed, but because they know the app is
already logged in. They close the tab, open the app and finish the task there. Every web
analytics setup records that as a drop-off. It is the opposite: it is a user choosing the
cheaper path.

The share is usually small, often only a low single-digit percentage of login attempts, but
it lands precisely on the metric that gets reported upwards. You cannot detect it from the
web side at all. It only becomes visible when the app emits something like an "app opened,
already authenticated" event that can be joined to the same person, which is exactly the
signal most app instrumentations do not send.

## 3. Two Objects of native Authentication Measurement

Once you accept that the funnel is the minority case, native authentication analytics
splits cleanly into two objects. They need different events, different KPIs and usually
different owners.

| Object                   | Who it covers                                        | Core question                                          | Typical share of app users |
| ------------------------ | ---------------------------------------------------- | ------------------------------------------------------ | -------------------------- |
| **Login flow**           | New installs, guests, users who lost their session    | Can somebody who needs to log in actually do it?       | 15% to 25%                 |
| **Authentication state** | Everybody who is already logged in                    | Does the authenticated state survive, and when not why? | 75% to 85%                 |

### 3.1 Login Flow (a Minority of App Sessions)

This is the part that transfers from the web with only small changes. You still want the
full journey: which methods were offered, which one the user picked, whether the
[passkey](https://www.corbado.com/glossary/passkey) ceremony completed, which error came back, whether a fallback
rescued the attempt or lost it. The event model is the same one described in our guide on
[authentication observability](https://www.corbado.com/blog/authentication-observability).

Two things do change. Errors arrive through platform APIs rather than the browser, so the
taxonomy is a different one: the codes in our overviews of
[native app passkey errors](https://www.corbado.com/blog/native-app-passkey-errors),
[Apple passkey error codes](https://www.corbado.com/blog/apple-passkey-error-codes) and
[Google Play Services passkey error codes](https://www.corbado.com/blog/google-play-services-passkey-error-codes).
And a new install is a distinct starting condition rather than another session.

### 3.2 Authentication State (the Majority)

This object has no web equivalent worth speaking of, which is why so few teams collect it.

The subject here is a condition that persists between attempts. The app opens and the user
is authenticated, anonymous or somewhere in between while a stored session is being
restored. Later the condition changes: a token expires, a server invalidates a session,
the user switches accounts, the user deliberately logs out or the app comes back from a
reinstall with nothing left in its sandbox.

Every one of those transitions is a fact about your product. Only one of them, the
deliberate logout, is something the user asked for. The rest are things that happened to
them, and each costs you the ability to send a push notification, personalize a screen or
recognize a returning customer. In an app, a lost session is a lost customer until they log
in again, and many never do.

Android has started turning one of these transitions into a platform feature.
[Restore Credentials](https://developer.android.com/identity/sign-in/restore-credentials)
lets an app store a restore key alongside the user's account. The key travels with an
Android-to-Android transfer or a cloud backup, so the app can sign the user in silently
the first time it opens on the new phone, before any screen is shown. Google has made it a
requirement of the
[Apps Experience Program](https://developer.android.com/distribute/aep/aep-req-restore-credentials),
with exemptions for banking, fintech, healthcare and government apps. For measurement that
cuts both ways: a silent restore is a successful authentication that no login funnel will
ever record, and device migration turns into a state transition you can name instead of a
hole in the data.

## 4. Six KPIs for Authentication State

Six metrics describe the second object well. They are deliberately defined so that a single
number can be tracked over time and broken down by OS, app version and device model.

| KPI                              | Definition                                                                                | Why it matters                                                                                                    |
| -------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| **Durable authenticated session rate** | Share of app sessions that start already authenticated                                | Headline health metric. A slow decline is the earliest signal that something in session handling regressed          |
| **Unexpected logout rate**       | Authentication losses per 1,000 authenticated app sessions, excluding explicit logouts      | The native equivalent of a failed login. Usually the single most actionable number in this list                     |
| **Authentication retention**     | Share of installs still authenticated after 7, 30 and 90 days                               | Turns authentication into a retention curve you can compare across app versions the same way you compare crashes    |
| **New-install activation rate**  | Share of new installs that reach an authenticated state at all                               | Where the classic funnel still applies, and where onboarding changes become measurable                              |
| **Authenticated app-usage rate** | Active app sessions belonging to authenticated versus anonymous users                        | Separates the app's real logged-in population from browsing traffic, which is what personalization depends on       |
| **Reinstall recovery rate**      | Share of users who authenticate again after a reinstall, an offload or a device migration    | Reinstalls are a large, invisible source of churn. This is the number that tells you how much of it you get back    |

The last one deserves a note, because it is the one most often misdiagnosed as a credential
problem.

Passkeys survive a reinstall. They are stored by the platform credential manager, in
[iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain) or
[Google Password Manager](https://www.corbado.com/blog/how-to-use-google-password-manager), not by your app. What
does not survive is the session your app was holding. On Android, uninstalling removes the
app sandbox and the app's Android Keystore entries with it, so a reinstalled app starts from
nothing unless Auto Backup restored something. On iOS the picture is softer: keychain items
have historically outlived app deletion, although Apple has never documented that as a
guarantee and
[briefly changed the behavior in an iOS 10.3 beta](https://developer.apple.com/forums/thread/72271)
before reverting it. Offloading an app, which iOS offers to free storage, keeps documents
and data and therefore behaves differently again.

The platforms are closing part of this gap, and it is worth being precise about which
part. Restore Credentials covers the move to a new device. It deliberately stops short of
a reinstall, because Android reads uninstalling an app as an intent to delete the restore
key, the same way it reads an explicit sign-out. Apple has announced nothing of the same
shape for general apps. Its
[Automatic Sign-In API](https://developer.apple.com/documentation/automaticsigninapi) does
place a sign-in token on the Apple Account so a person stays signed in across their
devices, but it runs through the Video Subscriber Account framework and is scoped to
media-streaming services, so a retailer, a bank or a marketplace cannot use it.

So the recovery path is a login, and it is a login by people who already own a working
credential and simply need to be asked for it well. Measuring how many of them get through
is measuring how much of your install base you keep.

## 5. Signals that only exist inside an App

The KPIs above are only computable if the app emits things a browser never had to. Four
groups matter.

### 5.1 App Lifecycle Events

The most important event in native authentication analytics is also the most boring: the app
was opened, and here is the authentication state it opened in. Without it there is no
denominator for anything in section 4, and no way to detect the web-to-app switch from
section 2.3.

Lifecycle also constrains everything else. An app gets backgrounded, suspended and killed by
the operating system, so an SDK has to finish or safely park its work at those boundaries
rather than assume a page unload it can hook.

### 5.2 Authentication States and Logout Reasons

A single boolean for "logged in" throws away the interesting part. The state model we use
has four values, and every app session sits in exactly one of them:

- **unknown**, before anything has been determined
- **anonymous**, an intentional guest session
- **restoring session after install**, the transient window in which a fresh install tries
  to re-authenticate silently
- **authenticated**

When a session leaves the authenticated state, three named reasons account for the cases
where nothing went wrong:

- **explicit logout**, the user asked for it
- **server-side invalidation**, your backend ended the session
- **account switching**, a deliberate change rather than a failure

Everything that is left over is by definition an unexpected logout, and that residual is
the number worth watching. The diagram below shows why the model has to be built this way.
You never log this metric directly. It is what remains once the named exits are
subtracted.

Teams that only log "user is logged out" end up with the sentence we hear constantly: it is
unclear why users lose their session, which makes it hard to do anything about it.

### 5.3 Device Attributes that decide Passkey Eligibility

On the web, whether a passkey prompt could ever have worked is answered by
[client capabilities](https://www.corbado.com/blog/webauthn-client-capabilities). In an app the equivalent set is
different, and it is available directly from the platform rather than inferred from a
[user agent](https://www.corbado.com/blog/client-hints-user-agent-chrome-safari-firefox). This is the attribute set
our own app-side client environments carry:

- **App name and version** plus **device brand and model**, which is how a regression gets
  attributed to a release rather than to "mobile"
- **OS and OS version**
- **Screen lock method**: none, passcode or a biometric class. iOS reports the biometry
  modality, Android reports the biometric strength class. A device with no screen lock cannot
  create a platform passkey at all, so this attribute alone explains a share of enrollment
  failures
- **Bluetooth availability**, the proxy for whether the cross-device (hybrid) path is usable
- **Google Play Services version** on Android, which Google-backed passkeys depend on and
  which is absent on AOSP and Huawei devices
- **Locale** and **screen geometry**, for segmentation and for spotting UI-driven drop-off

None of this requires PII. It is device and build metadata, and it is what turns "passkeys
fail sometimes" into "passkeys fail on this OS version, on these models, at this step".

### 5.4 Credentials that were available and not used

There is one native-only signal that has no clean web counterpart and is worth designing
for.

Both platforms let an app ask for credentials that are immediately available on the device,
without falling back to a [QR code](https://www.corbado.com/blog/qr-code-login-conversion) or a security key. On
iOS that is the `preferImmediatelyAvailableCredentials` option on
`ASAuthorizationController`; on Android it is the
[`preferImmediatelyAvailableCredentials` field](https://developer.android.com/identity/passkeys/sign-in-with-passkeys)
on `GetCredentialRequest`. Apps use it to show a passkey overlay on launch, before the user
has typed anything.

That request produces a genuinely new fact: a passkey existed locally, the user saw it, and
they logged in with something else anyway. On the web that would look like an ordinary
password login. In an app it is a measurable signal that your passkey UX lost a race it
should have won, and it belongs in the analytics rather than being discarded as a cancelled
prompt.

## 6. Where the Login runs decides what you can measure

Before any of this can be collected, one architectural question has to be answered per flow:
where does the login actually execute? Our guide on
[native app passkeys](https://www.corbado.com/blog/native-app-passkeys) covers the implementation trade-offs. For
measurement, the four cases behave very differently.

| Integration           | What happens                                                            | Measurement consequence                                                                                          |
| --------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| **Fully native**      | Login runs entirely in native code with the platform credential APIs      | Web instrumentation cannot see it at all, so it takes a native SDK                                               |
| **System WebView**    | Login opens Safari or Chrome Custom Tabs, as in an OAuth flow             | Web instrumentation works, but the journey has to be marked as app-initiated or it pollutes your web numbers      |
| **Embedded WebView**  | Login runs in an app-owned WebView                                        | Web instrumentation is unreliable: storage, cookies and navigation behave differently, and Conditional UI is out  |
| **Hybrid**            | Parts native, parts in a WebView                                          | Both sides have to emit into the same journey, or every user shows up as two half-journeys                       |

The failure mode here is subtle and common. A team instruments the web, sees app traffic
appear in the dashboard because the login happens in a System WebView, concludes the app is
covered, and never notices that app-initiated journeys are being averaged into web ones.
[In-app browsers](https://www.corbado.com/blog/passkeys-in-app-browsers) have their own quirks on top of that.

## 7. Constraints on a native Authentication SDK

Adding a script tag to a website is close to free. Adding a dependency to a native app is
not, and the teams who run large apps will say so within the first five minutes of any
conversation. Four constraints come up every time.

### 7.1 Stability before Completeness

Google Play publishes explicit thresholds. An app whose
[user-perceived crash rate](https://developer.android.com/topic/performance/vitals/crash)
reaches 1.09% of daily active users, or whose
[ANR rate](https://developer.android.com/topic/performance/vitals/anr) reaches 0.47%, is
likely to become less discoverable on Google Play, with an 8% per-device threshold on top.
Analytics is not worth a share of that budget.

The design conclusion is unusual for an analytics product: when in doubt, drop events. Stop
transferring, park the queue, do nothing. An SDK that loses a percentage of its data is
recoverable. An SDK that contributes to a crash rate gets removed from the app, and then you
have no data at all.

Two related requirements follow. Initialization has to be explicit rather than automatic, so
nothing runs before the host app decided it should. And there has to be a remote off switch,
so the SDK can be paused without shipping a release through app review.

### 7.2 No Method Swizzling

Web analytics gets autocapture almost for free. You patch a few globals, listen to the DOM
and collect a rich picture without the host application doing anything. The native
equivalent is method swizzling, which is roughly the Objective-C runtime version of
monkey-patching, and mature app teams reject it on sight because it makes crashes
unattributable and behavior version-dependent.

That removes the shortcut and forces a better design: the app emits explicit, typed events
from the places that already know what happened, its own login, session and lifecycle
services. The integration is a single adapter rather than a hook into the runtime. It is more
work up front and considerably easier to reason about afterwards.

### 7.3 Consent split into essential and analytical

Consent frameworks routinely remove a quarter of app traffic from analytics. That is
acceptable for product analytics and painful for debugging, because you cannot investigate a
technical failure that a consent rule deleted.

The split that resolves it is to tag events by purpose rather than to gate the whole SDK.
Error and diagnostic events are necessary to operate the service; behavioral time series are
analytical. Collect the first under essential consent and hold them to a shorter retention,
process the second only where analytical consent exists. This is not native-specific, but
apps are where the 25% actually hurts.

### 7.4 Lifecycle-aware Delivery

The remaining requirements are the ordinary ones that get forgotten: batch uploads with
low priority instead of a request per event, graceful stopping when the app is
backgrounded or hibernated, a networkless mode for the situations where the app
deliberately stops talking to the network and a small binary. App teams count kilobytes
because their users do.

## 8. Rollout Order that works

Instrumenting all of this at once is a large project. It does not have to be one, and the
sequence below front-loads the parts that pay off fastest.

1. **Errors first.** Ship error and failure tracking before anything else. It can usually be
   collected under essential consent, it is immediately useful, and it answers the question
   app teams actually have open right now, which is why passkey attempts fail on specific
   devices
2. **App-open state second.** One event carrying the authentication state at launch unlocks
   the durable session rate, the authenticated usage rate and the web-to-app blind spot from
   section 2.3
3. **Logout reasons third.** Now the unexpected logout rate becomes computable, and it is
   usually the first metric that changes somebody's roadmap
4. **Full login flow fourth.** The funnel that transferred from the web is the least urgent
   piece, because it covers the smallest population
5. **Reinstall and migration last.** Most difficult to attribute, and worth doing once the
   first four are stable

The ordering is deliberately the opposite of how web instrumentation usually gets built,
where the funnel comes first. In an app, the funnel is the smallest object you are measuring.

## 9. How Corbado can help

Everything above starts with one thing: an authentication journey that stays one journey
even when it crosses a WebView, a redirect and an app restart.
[Corbado Observe](https://www.corbado.com/observe) is the authentication observability layer built for that. It
models each product channel as its own application (`web`, `ios`, `android`) inside one
project, so app-initiated journeys stop being averaged into web numbers, and it reconstructs
what happened per user rather than per session.

[Video: User search debugging](https://www.corbado.com/videos/features/user-search-debugging.mp4)

- **App client environments are first-class.** When a journey comes from an app, the
  environment carries the host app and its version, the device brand and model, the screen
  lock method, Bluetooth availability and the Google Play Services version. That is the
  attribute set from section 5.3, and it is what attributes a failure to a release or a
  device class instead of to "mobile"
- **Per-user journey reconstruction across sessions and devices**, which is what answers
  why one specific customer could not get in yesterday
- **Error classification with authentication semantics**, so a user cancelling a system
  prompt is not counted as a platform failure, broken down by OS, OS version and credential
  manager

Where the login runs decides how it gets instrumented. System WebView and hybrid flows are
covered by the web SDK today, marked as app-initiated so they stay separable from web
traffic. For fully native flows, the app-side event and client environment model is already
part of Observe, which is where the attributes above come from.

If you also want the native passkey implementation handled rather than measured,
[Corbado Connect](https://www.corbado.com/connect) ships iOS and Android SDKs for passkey login, enrollment and
management, so the ceremony does not have to be hand-built once per platform.

## 10. Conclusion

Native app authentication analytics is not web analytics with a smaller sample. The
population is inverted: most of your users are already logged in, so the login funnel
describes the exception while the authenticated state describes the product. Measuring that
state means new objects (app-open events, logout reasons, reinstall recovery), new KPIs and
an SDK that earns its place in a binary where a crash rate has commercial consequences.

The reason this matters more each year is that apps are where authentication is going. The
credential lives in the operating system, the ceremony runs on the device and
[over 80% of passkey failures](https://www.corbado.com/blog/authentication-intelligence) never reach a backend at
all. An app that cannot say why its users lost their session is guessing about the single
thing it spent the most money to achieve.
