LTV: как считать ценность пользователя по когортам
Как считать LTV по когортам, связать его с ARPU и retention, сравнить каналы и не выдать грубую оценку за пожизненную ценность пользователя.
Содержание статьи
Команда видит, что новый канал привёл много регистраций, и сразу спрашивает: “А сколько эти пользователи принесут?” Здесь появляется LTV. Метрика помогает связать поведение когорты с деньгами, но только если назвать горизонт, единицу пользователя и способ учёта выручки. Один средний LTV без этих условий часто создаёт больше уверенности, чем знаний.
Коротко
LTV, или lifetime value, показывает, сколько чистой выручки в среднем приносит пользователь за выбранный горизонт жизни. Для исторического расчёта это не магическое число на всю жизнь, а накопительная выручка когорты, разделённая на размер этой когорты.
LTV_N = cumulative net revenue from cohort during N / users in cohortLTV30 и LTV90 — разные метрики. Нельзя сравнивать их как одно и то же число или выдавать LTV30 за полную ценность пользователя.
- Всегда указывай горизонт: D30, D90, 6 месяцев или другой срок.
- Считай одинаковые когорты: по регистрации, первой покупке или первой активации.
- Используй net revenue, если сравниваешь экономическую ценность каналов.
- Сравнивай только зрелые когорты, которым уже исполнился выбранный горизонт.
- Для решения о закупке трафика связывай LTV с CAC, маржой и сроком окупаемости.
LTV, ARPU и ARPPU отвечают на разные вопросы
ARPU обычно смотрит на выбранный период: месяц, неделю или день. LTV накапливает выручку одной когорты с момента старта. ARPPU исключает пользователей без платежа и поэтому описывает только платящую часть базы. Эти метрики связаны, но не заменяют друг друга.
Если ARPU вырос в июле, это ещё не значит, что июльская когорта станет более ценной. Возможно, в ней много крупных разовых платежей. LTV по когортам заставляет посмотреть, сохраняется ли разница на D30 или D90.
| Метрика | Знаменатель | Какой вопрос задаёт |
|---|---|---|
| ARPU | активные пользователи периода | Сколько в среднем принесла аудитория за этот период? |
| ARPPU | платящие пользователи периода | Сколько в среднем заплатил пользователь, который уже платит? |
| LTV30 / LTV90 | пользователи одной зрелой когорты | Сколько чистой выручки накопила когорта за 30 или 90 дней? |
Начинай с исторического LTV по когортам
Для нового продукта лучше начать с наблюдаемого LTV, а не с модели, которая обещает точную ценность на годы вперёд. Возьми пользователей с одинаковым стартом, посчитай их net revenue на D1, D7, D30 и D90, а затем сравни когорты между собой.
Когорта может строиться по регистрации, первой активации, первой покупке или другому событию, которое действительно задаёт начало жизненного цикла. Выбор зависит от вопроса. Для оценки рекламного канала чаще подходит регистрация или первая активация; для повторных покупок — первая покупка.
| Параметр | Пример решения |
|---|---|
| Старт когорты | signup_at или первая успешная покупка |
| Единица | user_id, account_id или платящий workspace |
| Выручка | успешные платежи минус возвраты и скидки |
| Горизонт | D1, D7, D30, D90; только зрелые когорты |
| Разрез | канал, платформа, тариф или страна |
Кривая LTV важнее одного финального числа
Одинаковый LTV90 может складываться из разных сценариев. Одна когорта получает большую часть выручки в первый день и потом почти не растёт. Другая медленно набирает ценность за счёт повторных покупок или подписки. Для продукта это разные риски и разные решения.
На графике ниже paid social выглядит слабее уже на D7 и почти не догоняет органику к D90. Это не доказывает, что канал плохой сам по себе: нужно проверить CAC, маржу, состав кампаний и зрелость когорт. Но такой разрыв уже подсказывает, где искать причину.
Условный пример. Сравниваются зрелые когорты на одинаковых горизонтах; значения показывают net revenue на одного пользователя.
Какая выручка должна попасть в LTV
Для сравнения каналов LTV лучше считать на чистой выручке. Если один источник приводит много заказов, которые потом возвращают, его gross revenue будет выглядеть здоровее реальной экономики. То же относится к скидкам, комиссиям платёжных систем, налогам и отменённым списаниям.
В B2B-продукте важно выбрать правильную единицу. Если один аккаунт оплачивает workspace для 30 сотрудников, LTV на user_id может исказить историю. Для такого продукта полезнее считать LTV на account_id или workspace и отдельно показывать пользователей внутри аккаунта.
| Компонент | Что проверить |
|---|---|
| Платежи | учитываются только успешные операции |
| Возвраты | вычитаются из выручки в том же периоде или по согласованному правилу |
| Скидки | не теряются при переходе от gross к net revenue |
| Комиссии | понятно, считаем выручку или contribution margin |
| Валюта | все суммы приведены к одной валюте и таймзоне |
SQL для LTV30 и LTV90 по каналам
Ниже запрос для PostgreSQL. Таблица users содержит одну строку на пользователя с полями user_id, signup_at и channel. Таблица payments содержит платежи, возвраты и статус операции. Запрос берёт только когорты, которым уже исполнилось 90 дней, поэтому свежие регистрации не занижают LTV90 из-за незрелого окна.
D1, D7, D30 и D90 здесь означают первые 1, 7, 30 и 90 календарных дней после signup_at. Для продукта с другой логикой жизненного цикла нужно заменить стартовое событие и границы окна.
with cohorts as (
select user_id, signup_at, channel,
date_trunc('week', signup_at)::date as cohort_week
from users
where signup_at >= date_trunc('week', current_date) - interval '24 weeks'
and signup_at < current_date - interval '90 days'
),
normalized_payments as (
select user_id, paid_at,
case
when payment_type = 'refund' then -amount
when payment_status = 'succeeded' then amount
else 0
end as net_amount
from payments
where paid_at >= date_trunc('week', current_date) - interval '24 weeks'
and paid_at < current_date
),
select c.cohort_week, c.channel,
count(distinct c.user_id) as cohort_users,
round(coalesce(sum(p.net_amount) filter (where p.paid_at < c.signup_at + interval '1 day'), 0) / nullif(count(distinct c.user_id), 0), 2) as ltv_d1,
round(coalesce(sum(p.net_amount) filter (where p.paid_at < c.signup_at + interval '7 days'), 0) / nullif(count(distinct c.user_id), 0), 2) as ltv_d7,
round(coalesce(sum(p.net_amount) filter (where p.paid_at < c.signup_at + interval '30 days'), 0) / nullif(count(distinct c.user_id), 0), 2) as ltv_d30,
round(coalesce(sum(p.net_amount) filter (where p.paid_at < c.signup_at + interval '90 days'), 0) / nullif(count(distinct c.user_id), 0), 2) as ltv_d90
from cohorts c
left join normalized_payments p
on p.user_id = c.user_id
and p.paid_at >= c.signup_at
and p.paid_at < c.signup_at + interval '90 days'
group by 1, 2
order by 1, 2;LTV без CAC не отвечает на вопрос об окупаемости
Высокий LTV ещё не означает, что канал выгоден. Если привлечь пользователя стоит 300 ₽, а LTV90 равен 248 ₽, рост такой аудитории не окупается на этом горизонте. Если LTV считается по выручке, а CAC и расходы сравниваются с маржой, вывод тоже будет слишком оптимистичным.
Практическое сравнение начинай с одной пары: зрелый LTV выбранного горизонта и CAC той же когорты. Потом добавляй gross margin, возвраты и срок окупаемости. Не смешивай органику с paid traffic: у них разная стоимость привлечения и разная структура аудитории.
contribution LTV_N = LTV_N × gross margin; payback when contribution LTV_N >= CACЭто рабочая проверка на выбранном горизонте, а не универсальный прогноз всей жизни пользователя.
Где LTV начинает врать
Самая опасная версия LTV — одно среднее число для всех пользователей. Оно может расти из-за нескольких крупных клиентов, изменения mix каналов или случайного исключения возвратов. Ещё одна ошибка — назвать прогнозный LTV историческим фактом и забыть, что модель строится на предположениях о будущем поведении.
- Не сравнивай LTV30 свежей когорты с LTV90 зрелой когорты.
- Не дели выручку только на платящих, если называешь результат LTV всей когорты.
- Не смешивай user_id, account_id и workspace в одном отчёте.
- Не используй gross revenue, если возвраты и скидки заметно меняют экономику.
- Не принимай корреляцию LTV с каналом за доказательство причинности.
- Не масштабируй канал по LTV без проверки CAC, маржи и срока окупаемости.
Исторический и прогнозный LTV — разные вещи
Исторический LTV показывает то, что уже наблюдалось: сколько net revenue накопила когорта на D30 или D90. Прогнозный LTV пытается оценить будущие платежи после этого горизонта. Для прогноза нужны предположения о возвратах, оттоке, повторных покупках, марже и насыщении. Их можно моделировать, но результат нельзя подписывать просто как LTV без горизонта и пометки “forecast”.
На практике полезно держать оба слоя рядом. Историческая кривая отвечает за контроль качества каналов и продукта, а прогноз нужен для долгих решений вроде бюджета привлечения или годового контракта. Если прогноз сильно расходится с наблюдаемым D30/D90, сначала проверь модель и определения, а не выбирай более удобное число.
| Название | Что это означает | Для какого решения |
|---|---|---|
| LTV30 | наблюдаемая net revenue на пользователя за первые 30 дней | быстрый контроль когорты и канала |
| LTV90 | наблюдаемая накопительная выручка за 90 дней | сравнение зрелых каналов и окупаемости |
| Forecast LTV12M | модельная оценка на 12 месяцев | бюджет и долгосрочная экономика |
| Contribution LTV | выручка после маржи и согласованных переменных затрат | сопоставление с CAC |
Зрелость когорт и цензура данных
У LTV есть проблема правого края: последние когорты ещё не успели накопить платежи. Это называется right censoring. Их кривая закономерно ниже зрелых когорт, даже если будущий сценарий будет таким же. Поэтому LTV30 строится только по когортам, которым исполнилось 30 дней, а LTV90 — по тем, которым исполнилось 90.
Не подменяй незрелое окно прогнозом без отдельной маркировки. В таблице полезно хранить cohort_start, cohort_size, observation_end и maturity_days. Тогда любой читатель может понять, почему у одной строки есть LTV90, а у другой пока только LTV7. Это также помогает не принимать свежий маркетинговый канал за худший только из-за короткого наблюдения.
- Показывай maturity_days рядом с горизонтом LTV.
- Исключай незрелые когорты из исторического сравнения.
- Не заменяй missing future revenue нулём.
- Фиксируй дату среза, чтобы отчёт был воспроизводимым.
- Сравнивай каналы при одинаковой структуре когорт.
LTV × CAC: проверяй срок окупаемости
Сравнение LTV и CAC одним отношением удобно для презентации, но для управления бюджетом важнее время. Канал с LTV90/CAC = 1,4 может быть полезнее канала с отношением 2,0, если он окупается на D30, а второй — только после года и зависит от слишком неопределённого прогноза. Добавь к расчёту contribution margin и посмотри, на каком горизонте накопленная маржа пересекает CAC.
Это не означает, что любой канал обязан окупиться за 30 дней. Допустимый срок зависит от cash flow, типа продукта и договорённостей с бизнесом. Но правило должно быть заранее известно: например, “масштабируем канал только после достижения contribution LTV90 не ниже 1,2 CAC и при приемлемом возврате”. Такая рамка защищает от решений по одному красивому среднему.
payback_day = first day where cumulative contribution revenue >= CACЕсли пересечения нет на наблюдаемом горизонте, честно напиши “не окупился к D90”, а не достраивай результат до полной жизни без модели.
Как сформулировать вывод для команды
Слабый вывод звучит так: “LTV в органике выше, значит, нужно отключить paid social”. Он не говорит, достаточно ли объёма органики и окупается ли платный канал после учёта CAC.
Сильнее будет так: “У зрелых июньских когорт D90 LTV organic составил 248 ₽, referral — 238 ₽, paid social — 129 ₽. Разрыв появляется уже на D7 и почти не сокращается. Следующий шаг — сравнить CAC и contribution margin по кампаниям paid social; отключать весь канал до этого сравнения рано”. Такой вывод связывает цифру с решением, но не притворяется доказанной причинностью.
- Назови горизонт и зрелость когорт.
- Покажи единицу: пользователь, аккаунт или workspace.
- Разложи LTV по каналу, тарифу или платформе.
- Сравни LTV с CAC и contribution margin.
- Зафиксируй следующий шаг и владельца проверки.
Что почитать дальше
LTV лучше всего читать в связке с поведением и входом в продукт. Сначала проверь, возвращаются ли пользователи, затем посмотри, как они доходят до оплаты, и только после этого сравнивай ценность каналов.
Материалы по теме

Retention по когортам и каналам: как считать D1, D7 и D30
Как считать retention rate, D1/D7/D30 и когортную возвращаемость: выбрать return event, читать heatmap и находить слабые каналы.

ARPU и ARPPU: как считать выручку на пользователя
Как считать ARPU и ARPPU, выбрать корректный знаменатель, учитывать возвраты и скидки и не принять рост среднего чека за здоровую монетизацию.
Unit-экономика продукта: CAC, LTV и срок окупаемости
Как связать стоимость привлечения, маржинальную выручку и поведение когорт: разбираем CAC, LTV, payback period и типичные ошибки в unit-экономике.