Все материалы
Продуктовая аналитикагайдсредний

LTV: как считать ценность пользователя по когортам

Как считать LTV по когортам, связать его с ARPU и retention, сравнить каналы и не выдать грубую оценку за пожизненную ценность пользователя.

КейсПрактика10 июля 2026 г.обновлено 2 октября 2026 г.14 мин

Команда видит, что новый канал привёл много регистраций, и сразу спрашивает: «А сколько эти пользователи принесут?» LTV — это ценность пользователя за выбранный срок: сколько дохода или маржинального вклада в среднем накопила одна когорта от начала отношений с продуктом. Простыми словами, это ответ на вопрос, сколько денег приносит один человек за время наблюдения, а не сумма одной покупки. Метрика помогает связать поведение когорты с деньгами, но только если назвать горизонт, единицу пользователя и способ учёта выручки. Один средний LTV без этих условий часто создаёт больше уверенности, чем знаний.

Коротко

LTV, или lifetime value, показывает, сколько чистой выручки в среднем приносит пользователь за выбранный горизонт жизни. Для исторического расчёта это не магическое число на всю жизнь, а накопительная выручка когорты, разделённая на размер этой когорты.

Исторический LTV на горизонте N
LTV_N = cumulative net revenue from cohort during N / users in cohort

LTV30 и 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, а затем сравните когорты между собой.

Когорта может строиться по регистрации, первой активации, первой покупке или другому событию, которое действительно задаёт начало жизненного цикла. Выбор зависит от вопроса. Для оценки рекламного канала чаще подходит регистрация или первая активация; для повторных покупок — первая покупка.

Что зафиксировать до расчёта LTV
ПараметрПример решения
Старт когортыsignup_at или первая успешная покупка
Единицаuser_id, account_id или платящий workspace
Выручкауспешные платежи минус возвраты и скидки
ГоризонтD1, D7, D30, D90; только зрелые когорты
Разрезканал, платформа, тариф или страна

Кривая LTV важнее одного финального числа

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

На графике ниже paid social выглядит слабее уже на D7 и почти не догоняет органику к D90. Это не доказывает, что канал плохой сам по себе: нужно проверить CAC, маржу, состав кампаний и зрелость когорт. Но такой разрыв уже подсказывает, где искать причину.

Накопительный LTV по каналам, ₽ на пользователя

Условный пример. Сравниваются зрелые когорты на одинаковых горизонтах; значения показывают net revenue на одного пользователя.

OrganicReferralPaid social

Какая выручка должна попасть в LTV

Для сравнения каналов LTV лучше считать на чистой выручке. Если один источник приводит много заказов, которые потом возвращают, его gross revenue будет выглядеть здоровее реальной экономики. То же относится к скидкам, комиссиям платёжных систем, налогам и отменённым списаниям.

В B2B-продукте важно выбрать правильную единицу. Если один аккаунт оплачивает workspace для 30 сотрудников, LTV на user_id может исказить историю. Для такого продукта полезнее считать LTV на account_id или workspace и отдельно показывать пользователей внутри аккаунта.

Проверка денежного слоя
КомпонентЧто проверить
Платежиучитываются только успешные операции
Возвратывычитаются из выручки в том же периоде или по согласованному правилу
Скидкине теряются при переходе от gross к net revenue
Комиссиипонятно, считаем выручку или contribution margin
Валютавсе суммы приведены к одной валюте и таймзоне

SQL для LTV30 и LTV90 по каналам

Запрос написан для учебной базы симулятора SQL-аналитика. В payments — оплаты в долларах; возвратов в этой базе нет, в рабочем запросе их вычитают из суммы. Горизонт получает число, только когда он закрыт у пришедшего в последний день месяца, поэтому свежие регистрации не занижают LTV из-за незрелого окна.

D14, D30, D60 и D90 здесь означают первые 14, 30, 60 и 90 календарных дней после регистрации; для продукта с другим жизненным циклом замените стартовое событие и границы окна. За 30 дней июньская когорта принесла 7,60 доллара на человека у рекомендаций, 7,22 у органики и 4,58 у партнёров; июльская — 7,83, 6,70, 4,78 и 2,59 у платного поиска, запущенного 1 июля. Стандартная ошибка этих чисел — 0,35–0,70 доллара: рекомендации от органики неотличимы, платный поиск ниже всех с запасом. LTV60 есть только у июня, а столбец LTV90 пуст целиком: в базе 91 день данных, и девяносто дней не прожила ни одна месячная когорта. Это правило зрелости, а не поломка: на более длинной истории тот же запрос заполнит столбец сам. Пустая клетка здесь — честный ответ, ноль был бы ошибкой.

Накопительный LTV по месяцу регистрации и каналу; незрелые горизонты остаются пустыми
with revenue as (                 -- зерно: один пользователь
  select u.user_id, u.channel,
    cast(date_trunc('month', u.signup_date) as date) as cohort_month,
    cast(date_trunc('month', u.signup_date) + interval '1 month' as date) - 1 as month_end,
    coalesce(sum(case when p.paid_at - u.signup_date < 14 then p.amount end), 0) as rev_14,
    coalesce(sum(case when p.paid_at - u.signup_date < 30 then p.amount end), 0) as rev_30,
    coalesce(sum(case when p.paid_at - u.signup_date < 60 then p.amount end), 0) as rev_60,
    coalesce(sum(case when p.paid_at - u.signup_date < 90 then p.amount end), 0) as rev_90
  from users u
  left join payments p on p.user_id = u.user_id
  group by u.user_id, u.channel, u.signup_date
)
-- оплаты в базе полны по 30 августа: горизонт считаем, когда он закрыт у пришедшего последним
select cohort_month, channel,
  count(*) as cohort_users,
  case when month_end + 13 <= date '2026-08-30' then round(sum(rev_14) / count(*), 2) end as ltv_d14,
  case when month_end + 29 <= date '2026-08-30' then round(sum(rev_30) / count(*), 2) end as ltv_d30,
  case when month_end + 59 <= date '2026-08-30' then round(sum(rev_60) / count(*), 2) end as ltv_d60,
  case when month_end + 89 <= date '2026-08-30' then round(sum(rev_90) / count(*), 2) end as ltv_d90
from revenue
group by cohort_month, month_end, channel
order by cohort_month, channel;

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, сначала проверьте модель и определения, а не выбирайте более удобное число.

Как подписывать LTV в отчёте
НазваниеЧто это означаетДля какого решения
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», а не достраивайте результат до полной жизни без модели.

Payback-день когорты не читается по горизонтам D30 и D90

Возьмите органическую когорту с условного графика выше: 248 ₽ накопленной выручки на пользователя к D90. Пусть валовая маржа равна 70%, а привлечение одного такого пользователя стоило 140 ₽. Маржинальная часть кривой тогда выглядит так: 58,8 ₽ к D7, 117,6 ₽ к D30, 149,8 ₽ к D60, 173,6 ₽ к D90 — то есть 42%, 84%, 107% и 124% от CAC. Строчку «когорта окупилась» по этим четырём числам написать уже можно. Ответа на вопрос «когда» в них нет: переход через 140 ₽ случился где-то внутри тридцатидневного промежутка между D30 и D60.

Соблазн дотянуть интерполяцией понятен: 22,4 ₽ недостающей маржи при шаге 32,2 ₽ за месяц дают примерно D51. Но деньги внутри месяца приходят не ровными порциями. У подписки списание стоит на дате продления, у повторных покупок — на заказе, и если между D30 и D60 лежит одно крупное событие на D44, накопленная маржа пересекает CAC именно 44-го дня. Интерполяция ошибётся на неделю, а для месячной подписки payback по построению совпадает с датой очередного платежа, а не с серединой интервала.

Поэтому payback считают не по горизонтам отчёта, а по ежедневному накоплению: на каждый день жизни когорты — накопленная маржа на одного стартового пользователя, затем первый день, когда она дошла до CAC. CAC здесь приходит из таблицы затрат и соединяется по той же паре «неделя старта × канал»: иначе окупаемость июньской когорты будет измеряться июльским бюджетом, а при сезонной закупке это расхождение в разы.

У зрелости при этом требование слабее, чем у LTV90, и этим почти не пользуются. Когорте 45 дней: LTV90 у неё появится только через полтора месяца, но если накопленная маржа прошла 140 ₽ на 38-й день, окупаемость уже наблюдённый факт, а не прогноз. Обратную ситуацию нужно подписывать строго: у когорты, которая к своему 45-му дню до CAC не дошла, в отчёте стоит «не окупилась к D45». Пустая ячейка payback_day у свежей когорты не означает плохой канал — она означает, что наблюдение короче, чем срок возврата.

Монотонность кривой ломают возвраты. Крупный refund на D70 способен опустить накопленную маржу ниже CAC после того, как она уже его прошла, и тогда два обновления отчёта дадут разные payback_day для одной когорты. Договоритесь заранее, что считается окупаемостью — первое пересечение или устойчивое превышение на горизонте, — и храните это правило рядом с числом, как и дату среза.

Запрос ниже считает payback-день на учебной базе по месячным когортам. Расходов в ней нет, поэтому CAC задан в самом запросе и условен, как и маржа 70%: 3 доллара у платного поиска, 4 у партнёров, 5 у рекомендаций. При таком CAC июньские рекомендации окупились на 19-й день, партнёры — на 41-й; это механика расчёта, а не экономика каналов. У июльских партнёров и платного поиска payback_day пуст: за 30 наблюдённых дней маржа дошла до 3,34 и 1,81 доллара — «не окупились к D30».

Условный пример: строка payback-отчёта по органической когорте
ПолеЗначениеОткуда берётся
cohort_week2026-06-01неделя старта когорты; в запросах на учебной базе — месяц
cohort_users1 180знаменатель, зафиксированный на старте
cac140 ₽затраты канала за неделю / новые пользователи когорты
gross_margin70%согласованное правило маржи
margin_d30117,6 ₽ — 84% CAC168 × 0,7
margin_d60149,8 ₽ — 107% CAC214 × 0,7
payback_dayмежду D31 и D60первый день, где накопленная маржа ≥ 140 ₽
observed_days92сколько дней когорта прожила к дате среза
Первый день, когда накопленная маржа месячной когорты покрывает условный CAC
with acquisition_cost (cohort_month, channel, cac) as (
  -- учебная вставка: расходов на привлечение в учебной базе нет, CAC условный
  values
    (date '2026-06-01', 'partner', 4.00), (date '2026-06-01', 'referral', 5.00),
    (date '2026-07-01', 'paid_search', 3.00), (date '2026-07-01', 'partner', 4.00),
    (date '2026-07-01', 'referral', 5.00)
),
cohort as (                       -- observed_days: сколько дней прожил пришедший последним
  select user_id, signup_date, channel,
    cast(date_trunc('month', signup_date) as date) as cohort_month,
    date '2026-08-30' - (cast(date_trunc('month', signup_date) + interval '1 month' as date) - 1) as observed_days
  from users
  where signup_date < date '2026-08-01'
),
sizes as (
  select cohort_month, channel, count(*) as cohort_users
  from cohort
  group by 1, 2
),
daily as (                        -- зерно: когорта + канал + день жизни
  select c.cohort_month, c.channel, c.observed_days,
    p.paid_at - c.signup_date as day_age,
    sum(p.amount) * 0.70 as contribution   -- возвратов в учебной базе нет
  from cohort c
  join payments p
    on p.user_id = c.user_id
   and p.paid_at - c.signup_date <= c.observed_days
  group by 1, 2, 3, 4
),
cumulative as (
  select d.cohort_month, d.channel, d.observed_days, d.day_age,
    sum(d.contribution) over (
      partition by d.cohort_month, d.channel
      order by d.day_age
    ) / s.cohort_users as margin_per_user
  from daily d
  join sizes s on s.cohort_month = d.cohort_month and s.channel = d.channel
)
select c.cohort_month, c.channel, a.cac,
  min(c.day_age) filter (where c.margin_per_user >= a.cac) as payback_day,
  c.observed_days,
  round(max(c.margin_per_user), 2) as margin_per_user
from cumulative c
join acquisition_cost a on a.cohort_month = c.cohort_month and a.channel = c.channel
group by c.cohort_month, c.channel, a.cac, c.observed_days
order by c.cohort_month, c.channel;

Как сформулировать вывод для команды

Слабый вывод звучит так: «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 лучше всего читать в связке с поведением и входом в продукт. Сначала проверьте, возвращаются ли пользователи, затем посмотрите, как они доходят до оплаты, и только после этого сравнивайте ценность каналов.

Продолжить чтение
Вся библиотека