Engagement Analytics
DAU, WAU, MAU, stickiness, time-in-app, and activity heatmap — automatic with SDK init. Zero instrumentation.
Overview#
Engagement analytics answers a different question from conversion tracking. Conversions measure what users do (signup, purchase, level complete) — they require you to call trackConversion() at the right moments. Engagement analytics measures whether your app is actually being used — and you don't have to call anything.
As soon as Mobana.init() runs, the SDK manages a foreground heartbeat in the background. The dashboard fills in with the metrics every PM looks at first: DAU, WAU, MAU, stickiness (DAU÷MAU), time-in-app, a day-of-week × hour activity heatmap, and a lifecycle/recency breakdown.
Heartbeats are not billed on any plan. Engagement analytics covers every install, attributed or organic, at no additional cost. The two metered surfaces remain attributions and flow views.
Setup#
There is no engagement-specific SDK call. Just initialize the SDK as you normally would — the heartbeat pipeline starts automatically.
import { Mobana } from '@mobana/react-native-sdk';
// That's the entire setup. As soon as init() runs, the SDK starts
// sending foreground heartbeats. DAU, WAU, MAU, stickiness,
// time-in-app, the activity heatmap, and lifecycle/recency
// breakdown all populate automatically.
Mobana.init({ appId: 'YOUR_APP_ID', appKey: 'YOUR_APP_KEY' });For native iOS/Android or other non–React Native platforms, post to the /activity endpoint directly on the same 5-minute cadence the SDK uses.
How the Heartbeat Works#
- Foreground only. The SDK starts the heartbeat when the app foregrounds and stops it when the app backgrounds. Background time does not count toward time-in-app.
- 5-minute cadence. While the app is in the foreground, the SDK pings
/activityevery 5 minutes. A user with the app open for 22 minutes contributes 4 × 5 = 20 minutes of time-in-app. - Silent-success. Heartbeat failures never surface as errors. A flaky network just means a missing data point.
- Privacy-first. Only the install ID is sent — no device IDs, no PII. The same setTrackingEnabled() switch stops heartbeats alongside attribution and conversions.
Metric Definitions#
| Metric | Definition | Window |
|---|---|---|
| DAU | Distinct installs with ≥1 foreground heartbeat | Last 24 hours |
| WAU | Distinct installs with ≥1 foreground heartbeat | Last 7 days |
| MAU | Distinct installs with ≥1 foreground heartbeat | Last 30 days |
| Stickiness | DAU ÷ MAU, as a percentage | Today vs last 30 days |
| Time in App | Average foreground minutes per active install (5-min granularity) | Today |
| Activity heatmap | Distinct active installs per day-of-week × hour-of-day bucket (UTC) | Selected time range |
| Lifecycle / recency | Install base split by last-seen recency (new, current, at-risk, dormant) | Selected period (3mo / 6mo / 1y / all) |
The DAU / WAU / MAU / Stickiness / Time-in-app stat cards always show wall-clock current values. The time range filter only affects the trend charts and heatmap underneath — this is intentional so the headline numbers always read “right now.”
Reading Stickiness#
Stickiness is DAU divided by MAU expressed as a percentage. It tells you what fraction of your monthly active users came back today. Rough industry benchmarks:
| Stickiness | Interpretation |
|---|---|
| < 10% | Low — users try the app but don't form a habit |
| 10–20% | Common for content / utility apps used occasionally |
| 20–50% | Strong — clear daily-habit traction |
| 50%+ | Exceptional — Facebook / WhatsApp / Snapchat territory |
Stickiness is the single best aggregate signal of product–market fit on a mobile app — it conflates “is the app valuable enough to open daily?” in one number. Tracking it over time tells you whether changes you ship move habit formation in the right direction.
Reading Time in App#
Time in App is the average foreground minutes per DAU, measured in 5-minute units. A user with the app open for 7 minutes contributes one 5-minute interval (5 min); a user with the app open for 22 minutes contributes four (20 min).
The 5-minute granularity is intentional — sub-minute precision would require continuous heartbeats and burn battery for no actionable benefit. Time-in-app is for spotting trends and comparing cohorts, not for billing.
Background time, time when the SDK isn't loaded yet, and time after the heartbeat is stopped (e.g. tracking-disabled mode) are not counted. If your app has long background sessions (audio playback, navigation), Time in App will under-report real usage.
Reading the Activity Heatmap#
The activity heatmap is a 7-day × 24-hour grid showing distinct active installs in each day-of-week / hour-of-day bucket (UTC). Hotter cells = more users active at that time. Use it to:
- Time push notifications, content drops, and live events for peak engagement
- Spot weekday vs weekend usage patterns
- Catch anomalies (e.g. a server outage shows up as a cold band)
- Plan deploys for low-traffic windows
Buckets are UTC, not user-local. For a globally distributed user base this is the sensible aggregation — a single “9pm” bucket spans many local times. For single-region apps, mentally shift the grid by your primary user time zone.
Reading the Lifecycle / Recency Breakdown#
The lifecycle bar splits your install base by how recently each install was last active:
- New — first activity inside the selected period
- Current — active in the last 7 days
- At-risk — active in the last 8–30 days but not recently
- Dormant — no activity in 30+ days
Watch the At-risk slice — it's the leading indicator of churn forming inside your MAU number. If At-risk grows faster than New, you have a retention problem brewing even while MAU still looks healthy.
The lifecycle bar uses its own period dropdown (3mo / 6mo / 1y / all) because the denominator is “installs whose first activity falls in the period” — that's a structurally different time window from the page-level range used by the other charts.
Filtering & Segmentation#
Every engagement chart respects the page-level filter bar — you can cross-filter the metrics by platform, country, and any UTM dimension to compare engagement across acquisition channels. Common comparisons:
- Do users from Meta stick more than users from TikTok?
- How does iOS time-in-app compare to Android?
- Does the new campaign creative bring users who actually return?
- Which countries have the highest stickiness?
Engagement charts require at least 7 days of data — DAU/WAU/MAU are degenerate on shorter windows. If you arrive with a 24h range inherited from another tab, the tab auto-snaps to 7d and surfaces a one-shot inline note.
Privacy & Opt-Out#
The same setTrackingEnabled() switch that controls attribution and conversion tracking also gates the heartbeat:
// Initialize with tracking disabled — no heartbeats are sent.
Mobana.init({
appId: 'YOUR_APP_ID',
appKey: 'YOUR_APP_KEY',
enableTracking: false,
});
// Or toggle later (e.g. after a consent flow):
Mobana.setTrackingEnabled(true); // heartbeats resume
Mobana.setTrackingEnabled(false); // heartbeats stop- When tracking is disabled, no heartbeats are sent and engagement metrics stop updating for that install.
- Heartbeats carry only the install ID (a locally-generated UUID) plus a timestamp — no device IDs, no PII, no fingerprinting signals.
- Existing engagement data for an install is not deleted when tracking is disabled mid-flight. Use Mobana.reset() to clear the install ID and start over with a new identity.
Roadmap#
The current engagement surface is the foundation — passive heartbeat, DAU / WAU / MAU, stickiness, time-in-app, activity heatmap, lifecycle / recency. What's coming next is built on the same data, so none of these will require new instrumentation in your app.
- Retention cohorts — Day-1 / Day-7 / Day-30 / Day-90 retention curves by install cohort, with side-by-side cohort comparison.
- LTV by acquisition source — average lifetime value per acquired user, broken down by source / medium / campaign. Crosses engagement with conversion revenue.
- Churn risk alerts — proactive flagging of at-risk users on the lifecycle bar, plus email alerts when the at-risk slice grows faster than new installs.
- Custom cohort builder — define cohorts by any combination of UTM parameters, country, app version, or install date, then compare DAU / stickiness / retention across them.
- Session analytics — sessions per user, time-between-sessions, and session-length distribution. Per-session granularity below the time-in-app aggregate.
Email [email protected] with what you'd like to see next. We prioritize based on customer signal.
Custom Integrations#
The React Native SDK manages heartbeats automatically. For native iOS / Android or any other platform, post to /activity directly on the same 5-minute cadence. See the /activity API reference for the request shape, debounce semantics, and the silent-success contract.