MAU растёт третий месяц подряд, а выручка стоит. Продукт стал лучше или маркетинг залил больше трафика? Сводный дашборд не ответит, когортная таблица ответит за вечер. Ошибка дорогая: бюджет уйдёт на людей, которые исчезнут через две недели.
Средняя цифра удержания смешивает новичков и старожилов
Отчёт говорит «удержание (retention) 20%», и эта цифра почти бесполезна. Внутри неё смешаны люди с разным стажем в продукте: новичок первого дня, тот, кто с вами два месяца, и старожил, который остаётся три года. Пока в продукт приходит всё больше новичков, среднее может сползать вниз даже при улучшившемся продукте. Бывает и наоборот: лояльная старая база маскирует провал у свежих пользователей.
Возьмём продукт, у которого в марте 10 000 старых пользователей, из них активны 60%, то есть 6000. Плюс мартовская когорта в 2000 человек, из которой через месяц активны 20%, то есть 400. Общая доля активных: 6400 / 12 000 = 53%.
В апреле маркетинг утроил закупку: пришли 6000 новичков, и благодаря новому онбордингу через месяц активны уже 25% из них, то есть 1500. Старая база не изменилась. Общая доля: 7500 / 16 000 = 47%. Среднее упало на 6 пунктов, хотя удержание новичков выросло на 5. Руководитель, который смотрит на сводную цифру, отменит удачный онбординг.
Статистики знают этот эффект давно. Классический случай описали Bickel и соавторы в журнале Science в 1975 году: по приёму в аспирантуру Беркли за 1973 год женщин в целом принимали реже, хотя внутри большинства факультетов разрыва не было. Разгадка была в составе заявок: женщины в основном шли туда, где отказывали почти всем, мужчины туда, где брали охотнее. Когда меняется состав групп, вывод о среднем может перевернуться, и у этого эффекта есть имя: парадокс Симпсона. С когортами происходит то же самое, только вместо факультетов месяцы прихода.
Когортный анализ раскладывает это среднее на части. Он смотрит, что происходит с людьми после первого прихода: по неделям и месяцам их собственной жизни в продукте. Обычный отчёт даёт одно число. А когорты покажут, что одни пользователи удерживаются на 35%, а другие на 12%. Что после переделки первых шагов для новичков удержание выросло на 6 пунктов. Что канал A приводит дешёвых людей, которые плохо окупаются. Каждый такой ответ меняет конкретное решение: куда нести бюджет, что чинить в продукте и кого перестать винить.
Срез показывает период, когорта показывает жизненный цикл
Привычные отчёты (их называют срезами, snapshot) показывают цифры за период: активные пользователи за ноябрь, выручка за декабрь, конверсия в оплату за неделю, отток за месяц. Каждая цифра по-своему честна. Но в ней смешаны пользователи разного «возраста», и на вопрос из первого абзаца она не ответит, как её ни уточняй.
Когортный анализ смотрит на данные иначе. Когортой называют группу пользователей (или аккаунтов, компаний), у которых было общее событие или условие. Вы собираете людей по этому признаку и следите, как каждая группа ведёт себя со временем. Важен уже не календарь, а то, сколько человек живёт в продукте.
Чаще всего когорту формируют по времени первого касания: все, кто зарегистрировался в первую неделю января или установил приложение в марте. Реже, хотя и не менее полезно, её собирают по источнику (пришедшие из TikTok Ads или по реферальной ссылке), по раннему поведению (создавшие три проекта за первую неделю) и по версии продукта или эксперименту (видевшие новый онбординг или попавшие в A/B-тест цен). Выбор признака определяет, на какой вопрос когорта ответит. Поэтому первым делом стоит понять, как устроена сама таблица.
Таблица выравнивает всех по возрасту
Формат почти всегда один. По строкам идут когорты, например недели регистрации. По столбцам стоит «возраст» когорты: неделя 0, 1, 2, 3 или день 0, 1, 7, 14. В ячейках стоит метрика: retention, выручка, конверсия, активность.
Смысл ячейки проще всего понять на числах. Если в когорте «2025-W01» было 1000 пользователей, а на третьей неделе активными остались 180, то retention этой недели равен 180 / 1000 = 18%. Неделя 2 у январской и у мартовской когорты означает одно и то же, поэтому их можно сравнивать честно, даже если между ними сменились сезон и рекламные каналы.
Читать таблицу удобно в двух направлениях. Строка показывает судьбу одной когорты: где кривая проседает и где выходит на плато. Столбец показывает, как меняется продукт: если «неделя 4» от когорты к когорте растёт с 12% до 16%, продукт стал удерживать лучше, и это видно без всякого среднего. Диагональ отвечает за календарь: если все когорты одновременно просели в одну и ту же неделю, ищите сбой, праздник или промо: продукт за одну неделю у всех сразу так не ломается.
Когорты отделяют рост входа от роста качества
Главный вопрос всё тот же: растёт ли качество продукта или вы просто наращиваете вход. Рост MAU может означать и больше регистраций при том же слабом удержании, и реальное улучшение удержания у новых когорт. На усреднённой цифре эти два случая неразличимы, на когортной таблице очевидны.
Раз таблица отделяет вход от удержания, она же измеряет эффект изменений. Выкатили новый онбординг: сравниваете когорты «до» и «после» по D1/D7/D30 retention, по скорости достижения ценностного события и по конверсии в оплату на первой-второй неделе. Тем же способом когорты сравнивают маркетинговые каналы по окупаемости. CPL и CPA тут плохие судьи, потому что дешёвый лид не равен хорошему, а retention, LTV и payback period по каналам расставляют всё по местам.
Когда базовые вопросы закрыты, таблица показывает вещи тоньше. Декабрьские когорты нередко удерживаются хуже из-за праздников, а январские лучше, потому что люди «начинают новую жизнь». Типичная дыра в жизненном цикле выглядит так: D1 отличный, D7 средний, а на D14 всё резко проседает. Это сигнал, что ценность одноразовая или привычка не закрепляется.
Здесь же видно, где проблема: в продукте или в привлечении. Если новые когорты держатся хорошо, но роста нет, дело в привлечении пользователей. Если людей приходит много, а свежие когорты держатся хуже старых, дело в продукте, в аудитории или в том, что обещает реклама.
С деньгами логика та же, только по оси времени жизни откладывают платежи: когда пользователь впервые платит, сколько платит к 30, 60 и 90 дню, как меняется ARPU и ARPPU от когорты к когорте. Когда кривые удержания и выручки становятся устойчивыми, на них можно прогнозировать будущую выручку и окупаемость каналов. Для этого нужно договориться, что именно лежит в ячейках.
В ячейках бывают удержание, деньги и активация
Чаще всего в ячейках стоит retention. Классическая формула для периода t: Retention(t) = ActiveUsers(t) / CohortSize, где ActiveUsers(t) означает пользователей когорты, совершивших целевое действие в период t. Считают её как D1/D7/D30, как weekly или monthly. Рядом стоит rolling retention (скользящее удержание): пользователь считается удержанным, если был активен в этот день или позже. Оно полезно, когда ценность не обязана проявляться строго по расписанию, например у сервиса бронирования путешествий, которым пользуются два-три раза в год.
Churn считается как дополнение до единицы: Churn(t) = 1-Retention(t). Churn и retention должны опираться на одно и то же определение активности, иначе одна команда отчитается о росте удержания, а другая о росте оттока на тех же данных.
Когорты выручки показывают в ячейке либо ARPU, либо накопленную выручку, либо долю сделавших покупку. LTV по когортам чаще считают как накопленную выручку на пользователя к определённому возрасту: LTV_30 = cumulative revenue до 30 дня / cohort size. В подписке к этому добавляют удержание платящих, средний чек и апгрейды с даунгрейдами.
Отдельно стоит смотреть активацию: не только остался ли человек, но и дошёл ли он до пользы. Это доля тех, кто за первые 24-72 часа пережил момент «ага, вот зачем это нужно» (aha-момент), сколько в среднем времени проходит до первого полезного действия и сколько людей прошли вводные шаги до конца. Когорты помогают разобрать и воронку: конверсию по шагам (регистрация → первое действие → повторное действие → оплата) в зависимости от того, сколько человек уже в продукте.
У каждого типа когорт свой предел
Временные когорты дают базовый «пульс» продукта: они просты, но причину различий не объясняют. Канальные нужны для оптимизации маркетинга и качества трафика: они не дают переплачивать за плохие каналы, но требуют приличной атрибуции. Если 30% регистраций приходят с пометкой «direct/none», канальная таблица покажет скорее качество разметки, чем качество каналов.
Поведенческие когорты («в первую неделю сделал ≥ 3 ключевых действия») помогают найти, что влияет на удержание и платежи. Здесь легче всего перепутать корреляцию с причинностью. Когорты по эксперименту или версии («новый онбординг против старого») ближе всего к причинности, но требуют аккуратного сбора данных и неизменных определений событий.
В B2B единицей анализа часто должен быть аккаунт: «аккаунты, созданные в январе», «аккаунты, где активировано три места», «аккаунты с подключённой интеграцией». Спутаете user и account, исказите и retention, и LTV. Если в компании-клиенте из 40 человек ушли 30, а оплата за аккаунт продолжается, пользовательский retention покажет катастрофу, а выручка не изменится. Ещё через квартал аккаунт, скорее всего, не продлит контракт, и тогда пользовательская когорта окажется опережающим сигналом.
Построение начинается с вопроса, а не с выгрузки
Всё начинается с бизнес-вопроса в измеримом виде. «Как у нас retention?» спрашивать бесполезно. А вот «выросло ли удержание новых пользователей после обновления онбординга?», «какой канал даёт лучший D30 retention?», «какое раннее поведение предсказывает оплату?» уже рабочие.
Дальше выбирают единицу анализа: user_id, device_id (осторожно, если нет логина), account_id для B2B, subscription_id для подписок. Ошибка здесь ломает всё остальное. Затем определяют событие, формирующее когорту: обычно signup, install или first_open, иногда first_purchase или первое событие активации. «Первая дата» должна быть однозначной. Параллельно задают целевое событие активности, и простой заход годится для этого, только если ценность продукта в самом заходе. Лучше брать событие, близкое к ценности: создал проект, отправил сообщение, сделал оплату, сгенерировал отчёт.
Остаётся выбрать шаг времени. Для B2C это дни и недели, для B2B недели и месяцы. Слишком мелкий шаг даёт шум, слишком крупный прячет сигнал. Ориентир: в каждой когорте должно быть хотя бы 100-200 пользователей. Иначе разница в 2-3 пункта между строками окажется случайной. После этого можно считать саму таблицу.
Последний шаг, интерпретацию, пропускают чаще всего. Таблица показывает, где когорты различаются, но не почему. Причину вытаскивают сегментацией (канал, гео, устройство, план), качественными исследованиями, разбором изменений в продукте и экспериментами.
Пример: когорта в 1 000 человек и каналы за $20 и $45
Пусть когорты нарезаны по неделе регистрации. В первой когорте 1000 регистраций; на второй неделе активны 250, на третьей 180, на четвёртой 150. Тогда W1 retention (неделя 2) = 250/1000 = 25%, W2 retention (неделя 3) = 180/1000 = 18%, W3 retention (неделя 4) = 150/1000 = 15%. Если следующая когорта (Неделя 2) даёт W1 = 30%, W2 = 22%, W3 = 20%, то у новой когорты выше наблюдаемое удержание.
Прежде чем праздновать, проверьте три вещи. Размер: если во второй когорте 300 человек, разница в 5 пунктов на W3 вполне укладывается в шум. Полноту: у второй когорты неделя 4 могла закончиться не у всех. Состав: если на второй неделе запустили партнёрскую рассылку по лояльной базе, когорта собрана из других людей. Чем красивее скачок, тем вероятнее, что первой найдётся ошибка в данных: сломанное событие, дубли, сменившийся источник. И даже если данные чистые, разницу между когортами рано записывать на счёт нового онбординга. Без эксперимента это наблюдение, и причину у него ещё предстоит найти.
Теперь деньги. Допустим, канал A приводит пользователя за $20, канал B за $45. Накопленная выручка на пользователя по когортам канала A: $4 к первому месяцу, $10 к третьему, $17 к шестому, $26 к двенадцатому. У канала B: $12, $33, $52 и $80. Канал A окупается между шестым и двенадцатым месяцем, примерно на восьмом. Канал B окупается между третьим и шестым, примерно на пятом. Отношение годовой выручки к CAC у A равно 26 / 20 = 1,3, у B 80 / 45 = 1,8.
По CPA канал A выглядит в 2,25 раза выгоднее, по когортам всё наоборот. Годовая выручка в 1,3 и 1,8 CAC ещё не прибыль: из неё вычтут себестоимость обслуживания, и у канала A запаса почти не останется. B возвращает деньги на три месяца раньше, и при ограниченном бюджете первый доллар разумно нести туда. Правило решения: если окупаемость канала по когортам дольше 12 месяцев и отношение выручки к CAC за год ниже 1,5, урежьте его бюджет вдвое и посмотрите на следующие две когорты.
Форма кривой подсказывает рычаг
Кривая удержания проседает в разных местах, и у каждого места свой рычаг:
- Провал между week0 и week1 почти всегда означает, что люди не доходят до первого результата: рычаг здесь во времени до ценностного события, доле дошедших до aha и шагах онбординга с самым большим отвалом.
- Провал на второй-третьей неделе говорит о привычке: нет повода вернуться, продукт не встроен в рутину, ценность одноразовая; работают частота ключевого действия, повторяемость сценария и триггеры возврата: уведомления, задачи, контент.
- Удержание в порядке, а денег мало, значит дело в монетизации: слабый paywall, неверная цена, непоказанная ценность платных функций, кривая упаковка, и разбирают это через конверсию в оплату по возрасту, накопительные когорты выручки и апгрейды с даунгрейдами.
Хорошая кривая выходит на плато. Если к восьмой неделе удержание продолжает снижаться на 2-3 пункта каждую неделю без признаков выравнивания, у продукта нет ядра пользователей, для которых он стал привычкой, и рычаги монетизации пока бесполезны. Чинить нужно то место, где кривая падает круче всего, потому что каждый пункт, сохранённый там, переносится на все последующие недели.
Когорты врут, когда незаметно меняются определения
Самая частая ловушка в том, чтобы считать активностью любой визит. В части продуктов «зашёл» не равно «получил ценность», и тогда retention выглядит нормально, а продукт не растёт. Данные тихо портит и смешение единиц анализа: если один человек ходит с двух устройств, а вы считаете device_id за пользователей, retention и LTV поедут.
Чаще всего забывают о неполных данных у свежих когорт (статистики называют это правой цензурой). Когорте, которой ещё нет тридцати дней, просто неоткуда взять удержание на 30-й день. Сравнивать полные данные с неполными без пометок нельзя.
Дальше идёт размер. В когорте на 50 человек один случайный крупный клиент искажает выручку. Лечится это минимальным размером когорты, укрупнением дней до недель и доверительными интервалами. Отдельная беда начинается, когда молча меняют определение события «active user», чтобы «улучшить retention на бумаге». Определения фиксируют как договорённости и версионируют трекинг, иначе вы сравниваете разные вещи. Сезонность, промо, сбои и изменения в каналах порой двигают когорты сильнее любой фичи.
Коварнее всего путаница корреляции и причинности в поведенческих когортах. «Те, кто сделал три действия, держатся лучше» может значить, что действие полезно, а может значить, что это и так были сильные пользователи. Развести одно от другого помогает только эксперимент (подтолкнуть часть людей к действию) или контролируемая сегментация.
Прежде чем строить, проверьте готовность данных: есть ли стабильный user_id или account_id, дата первого события, чёткое событие ценности, пишутся ли события без дыр и дублей, понятна ли временная зона. Если хотя бы одного из этих условий нет, сначала чините данные. А если retention падает именно у новых когорт, проверяйте по порядку: изменения в привлечении, качество онбординга и time-to-value, баги и краши, не сломалось ли само событие активности.
SQL-каркас для недельного удержания
Упрощённая схема weekly retention по дате регистрации и событию активности:
-- Пример: weekly retention по когорте регистрации
WITH cohort AS (
SELECT
user_id,
DATE_TRUNC(MIN(event_time), WEEK) AS cohort_week
FROM events
WHERE event_name = 'signup'
GROUP BY user_id
),
activity AS (
SELECT
e.user_id,
DATE_TRUNC(e.event_time, WEEK) AS activity_week
FROM events e
WHERE e.event_name = 'key_action' -- событие ценности
),
joined AS (
SELECT
c.cohort_week,
a.activity_week,
DATE_DIFF(a.activity_week, c.cohort_week, WEEK) AS age_week,
c.user_id
FROM cohort c
JOIN activity a
ON a.user_id = c.user_id
WHERE DATE_DIFF(a.activity_week, c.cohort_week, WEEK) >= 0
),
cohort_size AS (
SELECT cohort_week, COUNT(DISTINCT user_id) AS users
FROM cohort
GROUP BY cohort_week
),
retention AS (
SELECT
cohort_week,
age_week,
COUNT(DISTINCT user_id) AS active_users
FROM joined
GROUP BY cohort_week, age_week
)
SELECT
r.cohort_week,
r.age_week,
r.active_users,
cs.users AS cohort_users,
SAFE_DIVIDE(r.active_users, cs.users) AS retention_rate
FROM retention r
JOIN cohort_size cs USING (cohort_week)
ORDER BY r.cohort_week, r.age_week;
Под конкретный продукт подстраивают четыре вещи: событие формирования когорты (signup/install/first_purchase), событие ценности (key_action), единицу анализа (user_id/account_id) и гранулярность (DAY/WEEK/MONTH). Запрос написан на диалекте BigQuery; в PostgreSQL порядок аргументов DATE_TRUNC обратный, а разницу недель считают через деление интервала. Свежие когорты в результате дадут пустые ячейки справа, и это та самая правая цензура: на графике их стоит показывать пунктиром или не показывать вовсе.
Нужна ли когортная таблица при 300 регистрациях в месяц?
Чаще всего нет, и основатель, который в этом сомневается, прав. 300 регистраций в месяц дают около 75 человек в недельной когорте. При удержании около 20% доверительный интервал у такой когорты занимает примерно ±9 пунктов, так что почти любое недельное «улучшение» окажется случайным, а время честнее потратить на разговоры с пользователями.
Как пользоваться таблицей, решает масштаб. Если в недельной когорте меньше 200 человек, укрупняйте до месяцев и читайте таблицу как список вопросов для интервью. Если месячных когорт меньше 100, отложите таблицу и считайте вручную, сколько из последних 50 зарегистрировавшихся дошли до ценностного события и вернулись через неделю. Когда регистраций станет больше тысячи в месяц, когортный разрез становится основным инструментом.
Ритм вместо разовой выгрузки
Разовая выгрузка устаревает через месяц. Сильнее всего когортный анализ работает как постоянный монитор: раз в неделю смотреть свежие когорты по ранним метрикам, раз в месяц зрелые по D30/D60/D90, и каждый раз связывать изменения продукта и маркетинга с формой кривых.
Быстрый эффект он даёт в трёх ситуациях. Много регистраций, а продукт не растёт: таблица обычно показывает либо нормальный D1 при низком D7 (не закрепили привычку), либо низкий D1 (люди не доходят до ценности), и вы сразу знаете, что чинить: первые шаги новичка или повод возвращаться.
«Все говорят, что новый онбординг классный»: сравните когорты до и после по доле дошедших до ключевого действия и по D7/D30, и очень часто «нравится» оказывается не равно «работает». Спор маркетинга и продукта о падении выручки когортный разрез по каналам и возрасту превращает в диагностику: либо просел вход, либо продукт стал хуже удерживать новых везде.
Тогда рост MAU при стоящей выручке перестаёт быть загадкой. Держится всё это на одном ценностном событии, по которому строится первая таблица удержания. Если оно выбрано неудачно или пишется с пропусками, даже аккуратный ритм будет измерять не то.
