Аналіз Retention по когортам для мобільного додатку
Найпоширеніша ситуація: маркетинг рапортує про ріст установок, а MAU стоїть на місці. Проблема в тому, що без когортного retention-аналізу продукт не видить, коли саме користувачі йдуть — на другий день, через тиждень або після першої транзакції. Метрики Day 1, Day 7, Day 30 Retention — це не просто цифри для дашборда, а діагностичні інструменти, які вказують на конкретну точку відвалу.
Що таке когорта і чому агрегований retention брехує
Когорта — група користувачів, об'єднаних датою першої події. Найчастіше це дата встановлення (install_date), рідше — дата першої покупки чи реєстрації.
Без когортної розбивки retention рахується за формулою: активні сьогодні / активні за період. Це усереднення по всім користувачам змішує нових і старих. Додаток може показувати стабільний 30-денний retention 20%, хоча останні когорти деградують до 8% — просто старі, лояльні користувачі тягнуть середнє вгору.
Когортний аналіз рахує для кожної когорти окремо:
Day N Retention = unique_users_active_on_day_N / cohort_size
Де Day 0 — день встановлення, Day 1 — наступний календарний день (не 24 години). Різниця в інтерпретації дня важлива: Firebase за замовчуванням рахує по календарним дням у часовому поясі користувача, Amplitude та Mixpanel можна налаштувати обома способами.
Інструментарій і архітектура подій
Що трекати на клієнті
Мінімальний набір для retention-аналізу:
-
app_open— факт запуску (Firebase Analytics логує автоматично якsession_start) -
user_engagement— Firebase рахує це сам, але краще визначити свійmeaningful_action— дію, яка для вашого продукту означає «користувач знайшов цінність» -
install— атрибуція встановлення, потрібна для правильного визначення cohort_date
На iOS через Firebase SDK:
// AppDelegate або SceneDelegate
Analytics.logEvent("meaningful_action", parameters: [
"action_type": "first_purchase" as NSObject,
"item_category": product.category as NSObject
])
На Android (Kotlin):
firebaseAnalytics.logEvent("meaningful_action") {
param("action_type", "first_purchase")
param("item_category", product.category)
}
Ключова помилка — логувати app_open замість meaningful_action. Тоді retention рахується від факту запуску, а не від реального використання. Користувач відкрив додаток випадково — й він уже «retained» у цей день.
BigQuery + Firebase: справжній когортний аналіз
Firebase Console показує retention тільки у вигляді усередненої кривої. Для когортних таблиць потрібен експорт у BigQuery (безплатний Spark-план Firebase його підтримує з ліммітами).
Після підключення BigQuery eventi льються в таблиці типу events_YYYYMMDD. Запит для когортної таблиці Day 0–7:
WITH installs AS (
SELECT
user_pseudo_id,
DATE(TIMESTAMP_MICROS(event_timestamp), "Europe/Kyiv") AS cohort_date
FROM `project.analytics_XXXXXXXXX.events_*`
WHERE event_name = 'first_open'
),
activity AS (
SELECT
user_pseudo_id,
DATE(TIMESTAMP_MICROS(event_timestamp), "Europe/Kyiv") AS activity_date
FROM `project.analytics_XXXXXXXXX.events_*`
WHERE event_name = 'session_start'
)
SELECT
i.cohort_date,
COUNT(DISTINCT i.user_pseudo_id) AS cohort_size,
DATE_DIFF(a.activity_date, i.cohort_date, DAY) AS day_n,
COUNT(DISTINCT a.user_pseudo_id) AS retained_users,
ROUND(COUNT(DISTINCT a.user_pseudo_id) / COUNT(DISTINCT i.user_pseudo_id), 3) AS retention_rate
FROM installs i
LEFT JOIN activity a
ON i.user_pseudo_id = a.user_pseudo_id
AND a.activity_date BETWEEN i.cohort_date AND DATE_ADD(i.cohort_date, INTERVAL 30 DAY)
GROUP BY 1, 3
ORDER BY 1, 3
Цей запит дає таблицю: кожен рядок — когорта + день + retention rate. З неї будується теплова карта в Looker Studio, Data Studio чи прямо в Metabase.
Amplitude та Mixpanel як альтернатива
Для продуктів без BigQuery-експертизи Amplitude зручніше. Вбудований Retention Analysis будує когортні таблиці в декілька кліків. Але важливо правильно налаштувати User ID:
На iOS потрібно передавати стабільний ідентифікатор до першого identify:
Amplitude.instance().setUserId(user.stableId)
Amplitude.instance().logEvent("meaningful_action")
Якщо userId не задан, Amplitude створює device-based identity — й один користувач з двома пристроями рахується двома різними. Retention занижується.
Типичні помилки при настройці когортного аналізу
Змішення timezone. Якщо сервер логує eventi в UTC, а Firebase рахує Day N по локальному часу користувача — когорти розпливаються. Користувач встановив додаток о 23:50 за московським часом, сервер записав це в UTC наступного дня. Когорта зміщується на добу.
Пересчет cohort_date при переустановці. Після видалення й повторної встановки Firebase генерує новий instance_id і новий first_open. Користувач потрапляє в нову когорту. Якщо це не врахувати в аналітиці, retention когорт занижується — користувачі, що повертаються, виглядають як нові.
Малі когорти й статистичний шум. Когорта з 15 користувачів дає безсмисні цифри: ±1 користувач — це ±7% retention. Когортний аналіз дає надійні дані при розмірі когорти від 200–300 користувачів.
Візуалізація й продуктові висновки
Стандартна теплова карта виглядає так:
| Когорта | Розмір | Day 1 | Day 3 | Day 7 | Day 14 | Day 30 |
|---|---|---|---|---|---|---|
| 2024-01-01 | 420 | 38% | 22% | 14% | 9% | 6% |
| 2024-01-08 | 380 | 41% | 25% | 16% | 11% | 7% |
| 2024-01-15 | 510 | 29% | 18% | 11% | 7% | 4% |
Когорта від 15 січня різко гірша — збігається з релізом версії 2.3.0. Продукт видить це негайно й откатує або фіксить до того, як деградація розповсюдиться на весь користувальницький базис.
Що входить у роботу
- Аудит поточної схеми подій, перевірка наявності
first_open/meaningful_action - Настройка BigQuery-експорту з Firebase чи конфігурація Amplitude Retention
- SQL-запити для когортних таблиць з урахуванням timezone
- Дашборд у Looker Studio / Metabase / Redash
- Документація: словник подій, опис cohort_date logic
Терміни
Настройка з нуля: 3–5 днів (залежить від поточного стану аналітики та наявності BigQuery). Якщо eventi вже налаштовані — 1–2 дні на запити й дашборд. Вартість розраховується індивідуально після аналізу вимог.







