Разберите отчёт о месячном churn: почему запрос может занижать отток, если в знаменателе используются все п...

Разберите отчёт о месячном churn: почему запрос может занижать отток, если в знаменателе используются все пользователи, активные в начале или конце периода?

WITH users(user_id, active_on_jan1, active_on_jan31) AS (
  VALUES
    (1, TRUE,  FALSE),
    (2, TRUE,  TRUE),
    (3, FALSE, TRUE),
    (4, FALSE, FALSE)
)
SELECT COUNT(*) FILTER (WHERE active_on_jan1 AND NOT active_on_jan31)::numeric /
       COUNT(*) AS churn
FROM users
WHERE active_on_jan1 OR active_on_jan31;
Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Запрос занижает churn, потому что его знаменатель содержит не только пользователей, которые были активны в начале периода, но и новых пользователей, пришедших в течение периода. Корректный месячный logo churn обычно считается как доля пользователей, активных на начало периода и потерянных к его концу: ушедшие из начальной базы / начальная база.

В примере запрос даст 1 / 3, хотя корректный churn начальной базы равен 1 / 2: пользователь 3 присоединился в течение месяца и не должен уменьшать оценку оттока.

Исторический контекст

Метрики churn и retention появились как способ отделить изменение клиентской базы от её абсолютного размера. Простое число ушедших пользователей плохо сравнивает периоды: потеря 100 клиентов из базы 1 000 и из базы 100 000 имеет разный экономический смысл.

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

Постановка проблемы

В запросе объединяются пользователи, активные на начало или конец месяца. Поэтому в расчёт попадают как исходные пользователи, так и новые пользователи периода. Новые пользователи не могли быть потеряны до начала месяца, но включаются в знаменатель и искусственно уменьшают churn.

Ошибочный знаменатель особенно опасен при быстром росте продукта. Чем больше новых пользователей приходит в периоде, тем ниже может выглядеть churn даже при неизменном количестве ушедших клиентов.

Дополнительная проблема — неоднозначность слова активный. Для подписки это может быть действующий контракт, для маркетплейса — заказ в периоде, а для приложения — достижение определённого события. Без фиксированного определения сравнение churn между периодами ненадёжно.

Подробное решение

Для месячного churn сначала формируют начальную базу:

WITH users(user_id, active_on_jan1, active_on_jan31) AS ( VALUES (1, TRUE, FALSE), (2, TRUE, TRUE), (3, FALSE, TRUE), (4, FALSE, FALSE) ) SELECT COUNT(*) FILTER ( WHERE active_on_jan1 AND NOT active_on_jan31 )::numeric / NULLIF(COUNT(*) FILTER (WHERE active_on_jan1), 0) AS churn FROM users;

Числитель содержит пользователей, которые были активны на начало периода, но не активны на его конец. Знаменатель содержит только начальную базу. В примере результат равен 1 / 2, или 50%.

Важно различать logo churn и revenue churn. Logo churn считает потерянные аккаунты, а revenue churn — потерянную выручку или recurring revenue. Один крупный клиент может давать небольшой logo churn, но значительный revenue churn.

У пользователей с разной длительностью наблюдения обычный фиксированный месячный churn может быть недостаточен. Тогда применяют когортный анализ, survival-анализ или задают единое окно наблюдения. Для неполного текущего месяца нужно учитывать правую цензуру: пользователь ещё не успел пройти весь период наблюдения.

Компромисс простого churn — интерпретируемость. Он удобен для регулярного мониторинга, но скрывает дату ухода, повторные активации, временную неактивность и различия между сегментами. Поэтому его обычно дополняют retention, revenue churn, разбивкой по когортам и причинами отмены.

Ситуация из практики

В SaaS-продукте за месяц ушло 100 компаний. Команда могла разделить это число на конечную базу, на среднюю базу или на базу, объединяющую активных в начале и конце месяца.

Деление на конечную базу удобно для оценки текущего масштаба потерь, но смешивает churn с привлечением новых клиентов. Средняя база сглаживает изменение размера, однако остаётся приближением и может скрывать резкий приток или отток внутри месяца. Объединённая база наиболее явно смешивает разные популяции и плохо подходит для стандартного churn.

Команда выбрала начальную базу для monthly logo churn, а новых клиентов анализировала отдельно через activation и early retention. Для крупных клиентов дополнительно считала revenue churn. Это позволило не принимать рост числа новых регистраций за улучшение удержания существующих клиентов.

Что кандидаты часто упускают

  1. Вопрос: Нужно ли включать новых пользователей месяца в знаменатель churn?

Ответ: Обычно нет, если метрика называется churn начальной базы. Они не находились под риском ухода до начала рассматриваемого периода. Их следует учитывать в отдельной метрике, например в churn среди пользователей с достаточным временем жизни или в retention соответствующей когорты.

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

  1. Вопрос: Как учитывать пользователя, который был неактивен в конце месяца, но вернулся в следующем?

Ответ: Это зависит от определения потери. Для строгого churn на дату такой пользователь считается ушедшим, если на конец периода он не удовлетворяет критерию активности. Если бизнес различает временную паузу и окончательную отмену, вводят grace period, статус отменённой подписки или отдельную метрику reactivation.

Нельзя молча менять правило между отчётами: grace period уменьшит наблюдаемый churn, но увеличит задержку его фиксации. Выбранное окно нужно применять одинаково ко всем когортам и периодам.

  1. Вопрос: Почему общий churn может улучшиться, хотя churn каждого сегмента ухудшился?

Ответ: Такое возможно при изменении структуры базы: доля крупного сегмента с низким churn выросла, а доля сегмента с высоким churn уменьшилась. Это разновидность агрегирующего эффекта, поэтому общий показатель нужно проверять по стабильным сегментам, когортам и каналам.

Практически полезно сравнивать как минимум взвешенный общий churn и churn внутри сегментов с неизменными правилами формирования базы. Иначе решение о продукте может опираться на изменение состава пользователей, а не на изменение поведения внутри сегментов.