Glossary/Metrics and growth
N-day retention
Definition
N-day retention is the percentage of a cohort that is active on the Nth day after their starting event, where day zero is the day of the starting event itself.
D1, D7 and D30 are the shorthand almost every app team uses, and the label is doing more work than it looks. Two decisions sit underneath it and neither is usually stated: what "day N" is measured against, and what counts as active. Get either wrong and your retention curve is internally consistent and externally meaningless.
Day zero, and the off-by-one that follows it
The near-universal convention is that day 0 is install day and D1 means the day after. It is not the only convention in use, and the alternative — D1 meaning install day itself — shifts the whole curve by one position, which makes every cross-tool comparison wrong in the same direction.
| Convention | Day 0 | Counted in D1? | Elapsed time |
|---|---|---|---|
| Calendar day, install day = 0 | Monday | Yes | 20 minutes |
| Calendar day, install day = 1 | Monday = D1 | No, that is D2 | 20 minutes |
| Rolling 24-hour buckets | First 24h from install | No — still inside day 0 | 20 minutes |
| Calendar day in UTC, user in UTC+9 | Tuesday | Ambiguous | 20 minutes |
The first and third rows are the interesting pair. Calendar-day bucketing counts a twenty-minute gap as retention; 24-hour bucketing does not. Neither is wrong, but calendar bucketing systematically inflates D1 for apps whose users install in the evening — which is most consumer apps — and that bias does not appear anywhere in the output.
Pick one time zone and never change it
Cohort dates in UTC and session dates in local time will disagree for a predictable fraction of users, and the error is largest in the markets furthest from UTC. Store both timestamps with zone information, do the bucketing in one declared zone, and put that zone in the report header alongside the definition.
What counts as active
The second undeclared decision. "Active" can mean the app was opened, a session exceeded some duration, a screen was viewed, or a meaningful action occurred. Each produces a different curve from identical logs, and the gap between the loosest and strictest definitions is routinely larger than the difference between a good month and a bad one.
| Definition of active | Typical D1 effect | What it is good for |
|---|---|---|
| Any app open, including a push tap | Highest | Reach; easily gamed by notifications |
| Session longer than 5 seconds | Slightly lower | Filters accidental opens |
| Any screen beyond the splash | Lower | A reasonable default |
| A core product action | Lowest | Habit formation; the number worth optimising |
A background wake or a silent push must never count. It is the easiest way to manufacture retention, it is invisible in the aggregate, and it corrupts the one metric everything else is judged against. If your SDK reports a session on a background refresh, exclude it explicitly rather than assuming it does not.
The whole curve in one query
N-day retention is worth computing as a curve rather than as three isolated numbers. The shape between D1 and D30 tells you whether you have a leaky onboarding, a missing habit loop, or a healthy plateau, and none of those are visible from the endpoints alone.
-- Day 0 is install day. Activity is a session past the splash screen.
-- Both decisions are stated here rather than left to the reader.
WITH cohort AS (
SELECT user_id, DATE(installed_at) AS cohort_date
FROM installs
WHERE installed_at >= CURRENT_TIMESTAMP() - INTERVAL 90 DAY
),
active_days AS (
SELECT DISTINCT
c.user_id,
c.cohort_date,
DATE_DIFF(DATE(s.started_at), c.cohort_date, DAY) AS day_n
FROM cohort c
JOIN sessions s USING (user_id)
WHERE s.reached_first_screen -- not a background wake
AND DATE(s.started_at) >= c.cohort_date
),
sizes AS (
SELECT cohort_date, COUNT(*) AS cohort_size FROM cohort GROUP BY cohort_date
)
SELECT
a.day_n,
SUM(z.cohort_size) AS users_in_scope,
COUNT(DISTINCT a.user_id) AS retained,
ROUND(100.0 * COUNT(DISTINCT a.user_id) / SUM(z.cohort_size), 2) AS retention_pct
FROM active_days a
JOIN sizes z USING (cohort_date)
-- A cohort only contributes to day N once it has had N full days.
WHERE a.cohort_date <= CURRENT_DATE() - a.day_n - 1
AND a.day_n BETWEEN 0 AND 30
GROUP BY a.day_n
ORDER BY a.day_n;That correlated maturity filter is the important line. It lets a 60-day-old cohort contribute to D30 while a 5-day-old cohort contributes only up to D4, so the tail of the curve is not diluted by cohorts that have not lived long enough to reach it.
Reading the curve
- A steep D0→D1 drop is normal everywhere; the size of the drop is a first-session problem, not a product-market-fit verdict.
- A curve that flattens has found its habitual core. The plateau height, not D1, predicts long-term value.
- A curve that never flattens projects to zero users. No acquisition budget fixes that.
- Weekly spikes on days 7, 14, 21 indicate a weekly habit and are a reason to prefer classic retention over smoothed alternatives.
- Divergence by source is the fraud and quality signal — see retention rate for what each shape implies.
N-day is the label; the measurement rule underneath it is a separate choice. Classic counts day N exactly, rolling counts day N or later, and both are legitimately reported as "D7". Stating which one you used costs six words and prevents most retention disputes outright.
Free developer tools
A retention curve split by acquisition source is only as reliable as the campaign labels and the post-install destination behind it. Our free tools cover that link layer — campaign tagging, deep link routing and verification — so cohorts differ by the traffic you bought rather than by inconsistent tagging.
Open the free developer tools →Frequently asked questions
- What is N-day retention?
- It is the percentage of a cohort active on the Nth day after their starting event, most commonly reported as D1, D7 and D30. Day zero is conventionally the install day itself, so D1 means the following calendar day. The label describes the timing, not the measurement rule, which still has to be stated separately.
- Is day 0 or day 1 the install day?
- The dominant convention is that day 0 is install day and D1 is the next day, but the alternative convention exists and shifts an entire retention curve by one position. Since the labels look identical in both, confirm which one a tool or benchmark used before comparing anything, and state yours in the report.
- What counts as active for retention?
- That is your decision, and it changes the number substantially. Common options are any app open, a session longer than a few seconds, a screen past the splash, or a core product action. Background wakes and silent push refreshes should always be excluded, since counting them manufactures retention that no user actually produced.
- Why does time zone matter for N-day retention?
- Because day boundaries decide which bucket a session falls into. A user who installs at 23:50 and returns twenty minutes later counts as retained under calendar-day bucketing but not under rolling 24-hour buckets, and mixing UTC cohort dates with local session dates produces errors that scale with distance from UTC.
- Why does my D30 look better than my D7?
- Usually because immature cohorts are being included. If the query counts every cohort at every day index, recent cohorts drag D7 down while only older, self-selected cohorts reach D30 at all. Apply a maturity filter so a cohort contributes to day N only once it has had N complete days.
Related terms
- Retention rate — Retention rate is the percentage of a cohort of users who are still active after a defined period, measured from a fixed starting event such as install.
- Classic retention — Classic retention is the percentage of a cohort that is active on day N exactly, counting only activity on that specific day and ignoring activity on any other day.
- Rolling retention — Rolling retention is the percentage of a cohort that is active on day N or on any day after it, treating a user as retained if they ever returned at or beyond that point.
- Cohort analysis — Cohort analysis groups users by a shared starting event, usually their install date, and measures each group separately over time so that changes in behaviour can be separated from changes in acquisition mix.