Условие
Retention D7 (доля пользователей, которые вернулись в продукт через 7 дней после регистрации) упал с 40% до 32% за последний месяц. Как разобраться и что делать?
Решение
Подход
Шаг 1. Проверить сам факт.
- Сравнить с тем же периодом прошлого года — нет ли сезонности.
- Проверить, не сломалось ли логирование (количество новых регистраций нормальное?).
- Доверительный интервал: 8 п.п. — это значимое падение или шум?
Шаг 2. Разрезать когортами.
| Разрез | Что ищем |
|---|---|
| По дате регистрации | Один день / неделя или ровный тренд? Резкий обрыв = инцидент или релиз |
| По источнику привлечения | Просел ли какой-то канал? Поменялась mix? |
| По устройству / OS | Новый Android-релиз с багом? |
| По стране | Локальная блокировка / гео-расширение в плохой регион |
| По демографии | Изменился ли портрет нового юзера |
Шаг 3. Гипотезы.
- Mix shift. Стали лить трафик из дешёвого канала (TikTok / paid social), там пользователи качественно хуже. Source-level retention остался прежним, но взвешенная средняя упала.
- Onboarding регрессировал в недавнем релизе — меньше пользователей завершают активацию.
- Контент-проблема. Меньше нового контента → юзеру нечего смотреть → не возвращается.
- Push/email engine сломался — некому напоминать вернуться.
- Конкурент. Лояльные ушли к новой альтернативе.
Шаг 4. Декомпозиция воронки.
D7 = activation_rate × habit_loop_rate
activation_rate= доля новых, выполнивших ключевое действие в первые 24 часа.habit_loop_rate= из тех, кто активировался, вернулись D7.
Какой из двух множителей упал?
Шаг 5. Действия.
- Если просело mix трафика → переаллокация маркетингового бюджета / повышенный фильтр.
- Если activation → ревью onboarding-флоу, A/B на улучшение.
- Если habit loop → возвращающие триггеры, push-уведомления, content seeding.
- Если конкретный канал → конкретный fix.
SQL для скорости
WITH cohort AS (
SELECT
user_id,
signup_date::date AS d,
source, country, platform
FROM users
WHERE signup_date >= CURRENT_DATE - INTERVAL '60 days'
),
returned AS (
SELECT DISTINCT user_id, MIN(activity_date::date) AS first_active_after
FROM activity
WHERE activity_date >= CURRENT_DATE - INTERVAL '60 days'
GROUP BY user_id
)
SELECT
c.d, c.source, c.platform,
COUNT(*) AS cohort_size,
COUNT(*) FILTER (
WHERE r.first_active_after BETWEEN c.d + 6 AND c.d + 8
) AS retained_d7,
100.0 * COUNT(*) FILTER (
WHERE r.first_active_after BETWEEN c.d + 6 AND c.d + 8
) / COUNT(*) AS d7_pct
FROM cohort c
LEFT JOIN returned r USING (user_id)
GROUP BY 1, 2, 3
ORDER BY 1;Подводные камни
- «Просто плохой месяц» — игнорировать тренд. Если 8 п.п. — это вне 2 SD от исторического разброса, это не шум.
- Mix shift часто пропускают: per-source retention в норме, но средняя падает. Smart-decomposition по каналам обязательна.
- Логирование. Изменился ли определение «активности» в последнем релизе? Один баг в трекинге даёт 8 п.п. падения.
- Push-уведомления — главный драйвер D7 для многих продуктов. Если они сломались — retention летит мгновенно.
Эталонный ответ
Сегментировать падение по дате/каналу/платформе. Разложить D7 на activation × habit loop и понять, какой множитель упал. Частые причины: mix shift трафика, регрессия onboarding, сломанные push-уведомления, релизный баг. Действия — точно под причину; «давайте улучшим продукт в целом» — это не план.