retentionудержаниекогортный анализproduct-метрикиSQL

Retention: как считать удержание и кривую

2026-07-07 10 мин

Retention (удержание) — доля пользователей из когорты, которые вернулись в продукт спустя N дней после первого действия. Считается как отношение вернувшихся к размеру исходной когорты: R_N = U_N / U_0. Кривую строят по дням жизни когорты, а не по календарю; её выход на плато — сигнал того, что продукт нашёл свою аудиторию (product-market fit).

Что такое retention и зачем он нужен?

Retention отвечает на вопрос: сколько людей, пришедших в продукт, продолжают им пользоваться со временем. Это базовая метрика удержания в AARRR-фреймворке и ранний предиктор жизненной ценности пользователя (LTV). Если привлечение (acquisition) наполняет верх воронки, то retention определяет, насколько дырявое у вас ведро: при низком удержании любой платный трафик утекает быстрее, чем окупается.

Ключевое правило: retention всегда считают по когортам — группам пользователей, объединённых датой первого действия (регистрация, первая покупка, первый запуск). Средний retention «по всем сразу» смешивает новичков и старожилов и вводит в заблуждение. Подробный разбор когортной механики — в посте про когортный анализ retention в SQL.

Чем отличаются classic, rolling и range retention?

Есть три разных определения «вернулся», и они дают разные числа. Путать их на собеседовании — классическая ошибка.

Тип«Вернулся» означаетКогда применять
Classic (N-day)активен ровно в день Nпродукты с ежедневным ритмом (соцсети, игры)
Rolling (unbounded)активен в день N или позжередкие сценарии использования
Range (bracket)активен хотя бы раз в интервале [N; M]недельная/месячная активность, B2B

Сравнивать retention двух продуктов или двух периодов можно, только если совпадает и тип метрики, и определение активного действия.

Как считать N-day retention?

N-day retention — доля когорты, совершившая целевое действие в день с порядковым номером N, где день 0 — день первого контакта.

Формула:

R_N = (U_N) / (U_0)

где U_0 — размер когорты (все пользователи в день 0), U_N — число пользователей той же когорты, активных в день N.

«День N» отсчитывается от даты первого действия каждого пользователя, а не от общей календарной даты. Поэтому retention считают в терминах «дней жизни» (day 0, day 1, day 7, day 30), а не по календарю.

Разбор на числовом примере

Числа ниже — иллюстративные, не данные реальной компании.

Когорта: 1 000 пользователей зарегистрировались 1 марта (U_0 = 1000).

Знаменатель всегда U_0 = 1000, а не число вернувшихся накануне. Если делить на предыдущий день, получится другая метрика — «удержание между шагами», её тоже иногда считают, но это не N-day retention.

Churn (отток) для дня N — зеркало retention:

Churn_N = 1 - R_N

Для дня 7: Churn_7 = 1 - 0,22 = 78%. То есть 78% когорты в 7-й день неактивны (для classic-определения).

Что показывает кривая удержания (retention curve)?

Кривая retention — это график R_N по оси дней жизни когорты. У здорового продукта она имеет характерную форму:

Наличие плато — сильный сигнал product-market fit: у вас есть ядро пользователей, для которых продукт стал привычкой. Если кривая продолжает падать к нулю и плато нет — удержанного ядра нет, и масштабировать привлечение рано.

Форма важнее одной точки. Два продукта могут иметь одинаковый R_1 = 40%, но у одного кривая выходит на плато 20%, а у другого падает до 3% — второй не удерживает, сколько бы ни лил трафик.

# Простая эвристика "есть ли плато": сравнить наклон в хвосте с наклоном в начале
# Иллюстративные данные, не реальная компания
days = [1, 3, 7, 14, 30, 60, 90]
ret  = [40, 30, 22, 18, 15, 14, 13]  # проценты

early_drop = ret[0] - ret[2]      # день 1 -> день 7:  18 п.п.
tail_drop  = ret[-3] - ret[-1]    # день 30 -> день 90: 2 п.п.
print("Ранний спад:", early_drop, "п.п.")
print("Спад в хвосте:", tail_drop, "п.п.")
# Малый спад в хвосте относительно раннего => кривая выходит на плато

Как посчитать когортный retention в SQL?

Логика: определить дату первой активности каждого пользователя (когорту), затем для каждой последующей активности вычислить номер дня жизни и агрегировать. Ниже набросок на обобщённых таблицах — данные вымышленные.

WITH first_seen AS (          -- день 0 каждого пользователя
    SELECT user_id,
           MIN(event_date) AS cohort_date
    FROM events
    GROUP BY user_id
),
activity AS (                 -- номер дня жизни для каждого активного дня
    SELECT f.cohort_date,
           e.user_id,
           e.event_date - f.cohort_date AS day_n
    FROM events e
    JOIN first_seen f ON f.user_id = e.user_id
    GROUP BY f.cohort_date, e.user_id, e.event_date - f.cohort_date
)
SELECT cohort_date,
       COUNT(DISTINCT CASE WHEN day_n = 0 THEN user_id END)  AS cohort_size,
       ROUND(100.0 * COUNT(DISTINCT CASE WHEN day_n = 1 THEN user_id END)
                   / COUNT(DISTINCT CASE WHEN day_n = 0 THEN user_id END), 1) AS r1,
       ROUND(100.0 * COUNT(DISTINCT CASE WHEN day_n = 7 THEN user_id END)
                   / COUNT(DISTINCT CASE WHEN day_n = 0 THEN user_id END), 1) AS r7,
       ROUND(100.0 * COUNT(DISTINCT CASE WHEN day_n = 30 THEN user_id END)
                   / COUNT(DISTINCT CASE WHEN day_n = 0 THEN user_id END), 1) AS r30
FROM activity
GROUP BY cohort_date
ORDER BY cohort_date;

Это classic-определение (активность ровно в день N). Для range-retention меняют условие на day_n BETWEEN 7 AND 13 («неделя 2»), для rolling — на day_n >= 7. Отработать такие запросы на живой базе можно в SQL-тренажёре и на задачах по SQL.

Как retention связан с churn и LTV?

Три метрики — одна система. Churn — это ускользнувшая доля (Churn = 1 - R). А удержание напрямую задаёт, сколько в среднем пользователь «живёт» в продукте, что и превращается в LTV.

Простая связь для подписки с помесячным удержанием r (месячный retention) и средним доходом с пользователя ARPU:

LT = (1) / (1 - r), LTV ≈ ARPU × (1) / (1 - r)

Пример (иллюстративный): месячный retention r = 0,85, значит месячный churn = 15%. Средняя продолжительность жизни LT = 1 / (1 - 0,85) ≈ 6,7 месяца. При ARPU = 1000 руб/мес получаем LTV ≈ 6700 руб. Поднимите retention с 85% до 90% — и LT вырастет до 10 месяцев, а LTV — в полтора раза, без единого рубля на привлечение. Поэтому удержание — самый дешёвый рычаг юнит-экономики; детальнее в разборе LTV, CAC и payback.

Частые ошибки

Собрать когортный retention от начала до конца и увидеть, как меняется кривая при разных определениях активности, проще всего на практике — попробуйте построить такой запрос в SQL-тренажёре и разобрать продуктовые кейсы в разделе кейсов.

Практикуйся на реальных задачах
545 SQL + 538 Python задач с автопроверкой, 618 кейсов. Первые — без регистрации.
Построить когортный retention в SQL-тренажёре →