Why the web playbook doesn’t transfer
Most product-analytics advice is written for the browser, where a URL change is a free, reliable signal of what someone is doing. An app gives you none of that. Five differences change what you instrument:
- There is no page view. Navigation is a view stack, and nothing emits an event when it changes. Screen views exist only because you wired them — in Flutter, that is a route observer on your navigator; see the Flutter setup.
- Sessions come from lifecycle. A session starts when the app is foregrounded and ends when the OS backgrounds or kills it, not when a tab closes.
app_openandapp_closeare the boundaries. - Your users run every version you have shipped. New instrumentation only reaches people who update, so app version belongs on every event as a property — and in every comparison. “The funnel improved this week” is meaningless if the two weeks hold different version mixes.
- The network is optional. Events queue on the device and arrive late — sometimes hours late, after a flight or a dead zone. Expect out-of-order arrival, and be suspicious of any tool that quietly drops or re-dates them.
- The store owns install attribution. An app store sits between the ad click and the install, so your SDK first sees a person after they open the app. Attribution has to be stitched from what the store hands back, not from a referrer.
The events worth having on day one
A short plan you keep is worth more than a thorough one you abandon. A spine that answers real questions for almost any app:
app_installandapp_open— acquisition and return, the raw material for retention.screen_view— the path through the app, and the denominator for most funnels.signupandsignin— the identity boundary, where anonymous history becomes a person.feature_usedwith a property naming the feature — one event with a dimension, rather than forty event names you will regret.- The money moment:
trial_started,subscription_started, orpurchase. error_occurred— a crash-free session is not the same as one that worked.
Those are all well-known event names — standard kinds a tool can understand without configuration, which is what keeps a schema portable between tools and legible a year later. The free tracking plan generator turns this spine into a plan you can hand to whoever writes the code, and the event tracking guide covers naming and properties in more depth.
Retention, cohorted by install week
Retention is the metric mobile lives on, and a single blended percentage tells you nothing. Group users into cohorts by install week and track what share returns in each later week — the curve either flattens into a plateau, which is a core of people who found durable value, or decays toward zero, which no amount of installs will fix. What counts as a good number varies enormously by category, so read what a good retention rate is for the ranges and, more usefully, for how to read your own curve.
Two cuts earn their keep on mobile. Cohort by acquisition source, because paid installs and organic installs almost never retain alike, and cohort by app version, because a release that quietly breaks onboarding shows up first as a cohort that never comes back.
Activation is decided in the first session
Most of the users an app loses are lost before they ever see the product: an account wall, a permission prompt, an
empty state with nothing in it. Build that first run as an explicit
funnel — app_open → onboarding screen_view →
signup → first feature_used — and treat every prompt as a step in it rather than a
footnote. Permission decisions are close to permanent, since reversing one means a trip into system settings, so the
drop-off at that step is worth more attention than almost anything later in the flow.
One person, app and web
The questions that matter most usually cross the boundary: does someone who read the marketing site convert better
in the app, does support contact drive churn, is a mobile trial worth more than a desktop one. None of them survive
two disconnected tools. Send both surfaces to the same project and call identify() with the same user
id on each, and identity resolution merges the anonymous history into
one profile per person, across devices and platforms.
The instrumentation details that bite
- Flush when the app backgrounds. Otherwise the tail of every session dies with the process. A good SDK does it for you; verify it does.
- Put device context on every event. App version and build, device model, OS version, network type — these are the properties every later investigation slices by, and they cost nothing to attach at capture time.
- Gate on consent before capture, not after ingest. On mobile the prompt is yours to design, and “collected then deleted” is a much weaker position than never collected.
- Watch for event-name ceilings. Firebase Analytics caps an app at 500 distinct event names with 25 parameters each, which is the wall teams hit when they name events instead of using properties — see Pug vs Firebase Analytics.
Choosing a tool
Once the plan is clear, the tool question is narrow. It needs an SDK for the stack you actually ship; no ceiling on event names or properties; raw events you can read without standing up an export pipeline; and cohort retention and funnels as primitives rather than an add-on. Ownership is the last question, and the one that gets asked too late — an app’s event history is the record of everything users did, and where it lives is a decision you make once.
Pug is one open-source option: a Flutter SDK today, with native Android, iOS, and React Native SDKs in active development and landing by launch, self-hostable under AGPL-3.0. The mobile apps use case shows what that looks like end to end.