Retention по когортам и каналам: как считать D1, D7 и D30
Как считать retention rate, D1/D7/D30 и когортную возвращаемость: выбрать return event, читать heatmap и находить слабые каналы.
Содержание статьи
После DAU и DAU/MAU команда обычно приходит к самому важному вопросу: люди возвращаются сами или продукт каждый раз заново покупает внимание? Retention отвечает именно на это. Но метрика быстро становится мутной, если считать “возвращением” любое событие, смешивать молодые и зрелые когорты или смотреть общий D7 без каналов.
Коротко
Retention показывает, какая доля пользователей вернулась в продукт после первого значимого действия. Это не просто “сколько людей осталось”, а проверка продуктовой привычки, качества активации и качества привлечения.
- Сначала зафиксируй стартовое событие: регистрация, первая покупка, первая сессия или первая активация.
- Потом выбери return event: действие, которое правда означает возвращение к ценности.
- Смотри retention по когортам, а не только одним средним числом.
- Не сравнивай D7 у когорт, которым ещё не исполнилось семь дней.
- Обязательно дели retention по каналам, платформам и ключевым сегментам.
Что такое retention
Retention rate — это доля пользователей из когорты, которые вернулись и сделали нужное действие через заданный промежуток времени. Когорта обычно собирается по моменту старта: день регистрации, день первой сессии, неделя первой покупки или дата активации.
Здесь важны две границы. Первая — кто попадает в когорту. Вторая — что считается возвращением. Если в когорту попали все регистрации, а return event — любое открытие приложения, метрика будет отвечать на один вопрос. Если в когорту попали активированные пользователи, а return event — повторное core action, это уже совсем другой вопрос.
D7 retention = users_from_cohort_returned_on_day_7 / users_in_cohortВ числителе и знаменателе должны быть одни и те же пользователи по одной логике когорты. Нельзя считать когорту по регистрациям, а возвращение по техническим событиям.
Что считать возвращением
Плохое определение возвращения обычно выглядит слишком удобно: “пользователь сделал любое событие”. Так в retention попадают автологин, открытие пуша, техническая синхронизация или случайный визит на главный экран. В отчёте это выглядит как жизнь продукта, хотя пользователь мог не получить никакой ценности.
Рабочее определение зависит от продукта. Для игры возвращение — новая сессия или значимый игровой шаг. Для SaaS — повторное выполнение рабочего сценария. Для маркетплейса — поиск, просмотр товара, сообщение продавцу или заказ. Для BI-сервиса — открытый дашборд, запущенный запрос или отправленный отчёт.
| Продукт | Старт когорты | Возвращение лучше считать по |
|---|---|---|
| Mobile game | первая игровая сессия | session_start, level_started, battle_finished |
| B2B SaaS | первая активация в core workflow | project_updated, report_opened, task_completed |
| Marketplace | первый поиск или первая покупка | search, product_view, message_sent, order_created |
| BI / analytics | первый созданный отчёт | dashboard_viewed, query_run, report_shared |
D1, D7 и D30 не отвечают на один вопрос
D1 retention часто говорит про качество первого опыта: понял ли пользователь, зачем он пришёл, и удалось ли ему быстро получить ценность. D7 уже ближе к ранней привычке или повторному сценарию. D30 полезен для продуктов, где цикл использования длиннее, но он медленно обновляется и плохо подходит для быстрых релизных решений.
Из-за этого нельзя чинить D30 теми же действиями, которыми чинят D1. Если падает D1, смотри onboarding, первый сценарий, скорость до ценности и ошибки в первые минуты. Если D7 в порядке, а D30 слабый, проблема может быть в глубине продукта, повторной мотивации, контенте, ассортименте или регулярной пользе.
| Горизонт | О чём чаще говорит | Где легко ошибиться |
|---|---|---|
| D1 | первый опыт, понятность ценности, технические проблемы | перепутать пуш-возврат с настоящей активацией |
| D7 | ранняя привычка, качество канала, повторный сценарий | сравнить когорты, которым ещё не исполнилось 7 дней |
| D30 | долгосрочная ценность и повторяемость сценария | ждать D30 для решения, которое можно увидеть на D1/D7 |
Когортная таблица показывает форму проблемы
Один D7 в дашборде удобен для статуса, но слаб для диагностики. Когортная heatmap показывает, где именно меняется возвращаемость: в новых когортах, после конкретного релиза, в отдельном канале или на одном горизонте жизни пользователя.
Читать её нужно по строкам и столбцам. Строка отвечает за когорту: например, неделя регистрации и канал. Столбец отвечает за возраст пользователя: D1, D3, D7, D14, D30. Если вся новая строка светлее старых, проблема появилась в конкретной когорте. Если светлеет только D7+, пользователи проходят первый опыт, но не формируют повторный сценарий.
Значения условные. Светлые ячейки показывают, где пользователи перестают возвращаться. Прочерки означают, что горизонт ещё не дозрел.
Почему общий retention опасен
Retention редко падает равномерно. В большинстве рабочих кейсов есть источник, сегмент или платформа, где проблема появилась раньше остальных. Если один канал резко вырос по объёму и при этом приводит слабую аудиторию, общий D7 может просесть даже без изменений в продукте. Команда начинает чинить onboarding, хотя настоящая проблема сидит в закупке.
Поэтому общий retention лучше воспринимать как вход в расследование, а не как финальный вывод. Сначала разложи метрику на каналы, платформы и когорты. Потом проверь, не изменился ли микс трафика: иногда продукт не стал хуже, просто доля слабого paid-канала стала заметно больше.
Общий D7 может выглядеть терпимо, пока один быстро растущий канал тянет качество вниз.
SQL для D1, D7 и D30 по каналам
Ниже пример для продуктовой базы, где users содержит дату регистрации и канал, а events хранит события поведения. Запрос считает retention только по зрелым когортам: пользователь должен был зарегистрироваться достаточно давно, чтобы D30 уже мог наступить. Это защищает отчёт от частой ошибки, когда свежие когорты выглядят хуже просто потому, что им ещё не исполнилось 30 дней.
В примере используется календарный день: D7 означает активность на седьмой календарный день после регистрации. return_event_name нужно заменить на своё значимое событие возврата. Для продуктов, где важны точные 24-часовые окна, логику нужно менять на rolling interval.
with cohorts as (
select
user_id,
coalesce(channel, 'unknown') as channel,
signup_at::date as signup_day,
date_trunc('week', signup_at)::date as cohort_week
from users
where date_trunc('week', signup_at) >= date_trunc('week', current_date) - interval '16 weeks'
and date_trunc('week', signup_at) < date_trunc('week', current_date - interval '30 days')
),
activity as (
select distinct
user_id,
occurred_at::date as active_day
from events
where occurred_at >= date_trunc('week', current_date) - interval '16 weeks'
and occurred_at < current_date
and event_name = 'return_event_name'
)
select
c.cohort_week,
c.channel,
count(distinct c.user_id) as cohort_size,
round(
count(distinct c.user_id) filter (where a.active_day = c.signup_day + 1)::numeric
/ nullif(count(distinct c.user_id), 0),
3
) as d1_retention,
round(
count(distinct c.user_id) filter (where a.active_day = c.signup_day + 7)::numeric
/ nullif(count(distinct c.user_id), 0),
3
) as d7_retention,
round(
count(distinct c.user_id) filter (where a.active_day = c.signup_day + 30)::numeric
/ nullif(count(distinct c.user_id), 0),
3
) as d30_retention
from cohorts c
left join activity a on a.user_id = c.user_id
group by 1, 2
having count(distinct c.user_id) >= 100
order by 1, 2;Проверь склейку пользователей между anonymous_id и user_id, исключи ботов и тестовые аккаунты, зафиксируй таймзону и не меняй event_name между периодами. Retention очень чувствителен к грязному трекингу.
Где retention начинает врать
Retention выглядит строгой метрикой, но у него много бытовых ловушек. Самая частая — сравнить когорты разного возраста. Вторая — считать возвращением событие, которое не связано с ценностью. Третья — смотреть только процент и забыть про размер когорты: 40% из 50 пользователей и 12% из 50 000 требуют разного разговора.
Есть и менее очевидная ошибка: считать retention только по всем новым пользователям. Иногда продуктовая проблема находится не в новичках, а в текущей базе. Для зрелых продуктов полезно отдельно смотреть new user retention, current user retention и resurrected users: кто впервые пришёл, кто уже был активен, кто вернулся после паузы.
- Не смешивай календарный и rolling retention в одном отчёте.
- Не сравнивай D7 у когорт, которым меньше семи дней.
- Не считай push_open или login достаточным возвращением без проверки core action.
- Не делай вывод по проценту без размера когорты.
- Не забывай сегменты: канал, платформа, страна, тариф, lifecycle stage.
Как сформулировать продуктовый вывод
Слабый вывод звучит так: “D7 retention упал, нужно улучшать продукт”. Он не говорит, где проблема, кого она затронула и что делать завтра. Сильный вывод связывает метрику, сегмент, период и вероятную причину.
Например: “В июле общий D7 снизился с 18% до 14%. В органике D7 остался около 21%, а падение пришло из paid social: канал вырос в объёме в 2,1 раза, но его D7 просел до 8%. Продуктовая проблема в первом опыте не подтверждается без отдельного сигнала в органике; следующий шаг — разобрать кампании, креативы и соответствие обещания лендинга реальному onboarding”.
- Назови горизонт: D1, D7, D30 или другой.
- Покажи, какие когорты сравниваются и дозрели ли они.
- Разложи изменение на канал, платформу или сегмент.
- Проверь соседние метрики: activation, DAU/MAU, revenue, conversion.
- Отдели продуктовую гипотезу от гипотезы про качество трафика.
Три режима retention, которые нельзя смешивать
Классический N-day retention отвечает на вопрос: какая доля когорты была активна ровно на N-й день после старта? Он удобен для D1, D7 и D30, но чувствителен к тому, попал ли пользователь в конкретную дату. Unbounded retention спрашивает, возвращался ли пользователь в любой день начиная с N-го. Он лучше показывает, не потеряли ли мы аудиторию совсем, но обычно выше классического. Rolling retention фиксирует последний день активности и полезен для продуктов, где возврат может быть нерегулярным.
В отчёте всегда подписывай режим расчёта. Фраза “D30 retention = 22%” без уточнения может описывать три разные кривые. Для ежедневной игры классический D7 может быть естественным. Для B2B-инструмента, которым пользуются раз в неделю, лучше заранее договориться о weekly retention или о возвращении в течение окна. Сравнивать проценты можно только при одинаковом определении.
| Режим | Вопрос | Когда полезен |
|---|---|---|
| N-day | Был ли пользователь активен ровно на N-й день? | ежедневный продукт и контроль конкретного момента |
| Unbounded | Возвращался ли он в любой день после N? | оценка долгосрочного выживания когорты |
| Rolling | Как долго пользователь оставался до последней активности? | нерегулярный сценарий и длинный цикл задачи |
Зрелость когорты важнее красивой тепловой карты
Свежая когорта не имеет права участвовать в сравнении D30: у неё ещё нет тридцати дней наблюдений. В оперативном отчёте такие ячейки должны быть пустыми, а не нулевыми. Ноль означает “пользователь не вернулся”, пустое значение — “окно ещё не дозрело”. Если заменить незрелые ячейки нулями, последняя строка тепловой карты всегда будет выглядеть хуже предыдущих.
Сравнивай когорты после одинакового окна наблюдения и показывай размер базы. Маленькая когорта с высоким retention может быть нестабильной из-за нескольких пользователей. Для продуктового решения полезно смотреть не только процент, но и абсолютное число вернувшихся, доверительный интервал или хотя бы минимальный порог размера.
- D7 показывай только для когорт, которым исполнилось семь дней.
- Не превращай “ещё не наблюдали” в ноль.
- Фиксируй когорту по одному стартовому событию.
- Показывай cohort size рядом с процентом.
- Сравнивай сегменты на одинаковом горизонте и режиме расчёта.
От кривой retention к проверяемой гипотезе
Кривая сама по себе не говорит, что менять в продукте. Если D1 высокий, а D7 резко обрывается, проверь, получил ли пользователь вторую причину вернуться: напоминание, следующий рабочий результат, социальный контакт или повторяемый сценарий. Если D1 низкий во всех каналах, ищи проблему в первом опыте и активации. Если проседает только одна когорта после релиза, свяжи падение с платформой, версией и конкретным шагом.
Хорошая практика — заранее сопоставить каждый участок кривой с действием команды. D1 отвечает за первый результат, D7 — за повторную ценность, D30 — за устойчивость привычки или жизненного цикла. Это не универсальная трактовка, но она помогает перевести график из отчёта в список проверок.
| Сигнал | Что проверить | Следующий шаг |
|---|---|---|
| Низкий D1 | онбординг, трекинг первого результата, канал | исправить первый опыт или качество трафика |
| Нормальный D1, низкий D7 | повторная ценность, подсказки, незавершённые задачи | проверить сценарий второго визита |
| Падает только paid | кампания, обещание объявления, сегмент | разделить закупку и продуктовую гипотезу |
| Падает только iOS | релиз, ошибки, версия SDK | техническая диагностика до продуктового эксперимента |
Что почитать дальше
Для базовой сверки полезно посмотреть, как retention описывают аналитические платформы. Они по-разному называют режимы расчёта, но смысл один: нужно явно задать стартовое действие, действие возврата, окно времени и сегменты.
Материалы по теме

Когорты и retention в SQL: как считать возвращаемость по датам
Разбираем когортный retention в SQL: как определить дату старта, посчитать D1 и D7, собрать матрицу возвращаемости и сравнить каналы без самообмана.

LTV: как считать ценность пользователя по когортам
Как считать LTV по когортам, связать его с ARPU и retention, сравнить каналы и не выдать грубую оценку за пожизненную ценность пользователя.

DAU/MAU и stickiness: когда простая метрика начинает врать
Как читать DAU/MAU, WAU/MAU и stickiness без самообмана: когда метрика показывает привычку, а когда скрывает сезонность, платный трафик или редкий сценарий продукта.