lenec ru

← все посты

Как считать LTV в SaaS: разбор формул и где в них дыры

18K

LTV (lifetime value) — одна из тех метрик, которую все знают по названию, и почти все считают неправильно. Я регулярно вижу слайды с «LTV = $1200, CAC = $300, всё отлично, гоним», после которых выясняется, что LTV посчитан по упрощённой формуле, валидной только для гипотетического стационарного бизнеса. У реальной SaaS-компании эта цифра в 1.5–3 раза меньше.

Расскажу, какие формулы LTV существуют, когда какую применять, и где в каждой дыры. Без матанализа, но с конкретными примерами на цифрах.

Самая простая формула

ltv = arpu / churn_rate

Эту формулу учат на бизнес-курсах. ARPU — средний доход с пользователя в месяц. Churn rate — месячный churn в процентах. Деление даёт «среднее время жизни клиента, умноженное на ARPU».

На цифрах: ARPU = $50, monthly churn = 5%. LTV = 50 / 0.05 = $1000.

Где дыра. Эта формула верна только при допущении, что и ARPU, и churn rate стабильны во времени. На реальном SaaS они нестабильны:

  • Churn почти всегда выше у новых пользователей и снижается с возрастом когорты. Это U-shape или L-shape кривая.
  • ARPU растёт за счёт upsell и снижается за счёт downgrade.
  • Новые когорты ведут себя иначе, чем старые: продукт меняется, аудитория меняется.

Если в твоём продукте 50% новых пользователей уходят в первый месяц, а потом churn ровно 2% — простая формула даст $1000, реальный LTV будет $400.

Формула с учётом маржинальности

ltv = (arpu * gross_margin) / churn_rate

$50 ARPU не значат $50 в карман компании. Из них вычитаются costs of revenue: хостинг, поддержка, payment processing. Если gross margin = 70%, то реальный LTV = 50 * 0.7 / 0.05 = $700.

Эта поправка обязательна для любого расчёта LTV/CAC. Без неё ratio врёт в полтора раза — что критично, когда ты на основании этой цифры принимаешь решение о масштабировании маркетинга.

В B2C SaaS gross margin обычно 75–85%. В B2B с serious enterprise-поддержкой — 50–70%. В marketplace с физической логистикой — 20–40%.

Когортный LTV

Самая честная формула — посчитать LTV прямо по когортам, без обобщающих допущений.

WITH cohort_revenue AS (
    SELECT
        date_trunc('month', u.signup_date)::date AS cohort_month,
        date_trunc('month', s.payment_date)::date AS revenue_month,
        SUM(s.amount * 0.7) AS gross_profit  -- если хочется LTV с маржой
    FROM users u
    LEFT JOIN subscriptions s ON s.user_id = u.id
    GROUP BY 1, 2
),
cohort_size AS (
    SELECT
        date_trunc('month', signup_date)::date AS cohort_month,
        COUNT(*) AS users
    FROM users
    GROUP BY 1
)
SELECT
    cr.cohort_month,
    cs.users,
    SUM(cr.gross_profit) AS total_gross_profit,
    SUM(cr.gross_profit) / cs.users AS gross_profit_per_user
FROM cohort_revenue cr
JOIN cohort_size cs USING (cohort_month)
GROUP BY cr.cohort_month, cs.users
ORDER BY cr.cohort_month;

Получаешь по каждой когорте суммарный gross profit на пользователя. Это и есть LTV — но только для тех когорт, которые уже «дожили» до своего настоящего LTV.

Главная ловушка: данные обрезаются

Если когорта зарегистрировалась год назад, и в среднем клиент живёт 3 года, ты видишь только треть LTV. Все когорты младше 3 лет показывают заниженное число. Если ты возьмёшь среднее по всем когортам и назовёшь это LTV — получишь искажённую цифру.

Способов решить два.

Только зрелые когорты

Берёшь только когорты старше N месяцев, где N — медиана lifetime по историческим данным. Например, последние 36 когорт исключаешь, считаешь LTV только по тем, что 3+ года живут. Минус — данные старые, могут не отражать текущий продукт.

Прогнозный LTV

Строишь survival curve на исторических данных, экстраполируешь на будущее. Базовый подход — Kaplan-Meier estimator или фиттинг экспоненциальной модели:

import pandas as pd
from lifelines import KaplanMeierFitter

users = pd.read_parquet('users_with_churn.parquet')
kmf = KaplanMeierFitter()
kmf.fit(
    durations=users['lifetime_months'],
    event_observed=users['churned'],
)

# Survival на 60 месяцах
survival_60m = kmf.survival_function_at_times(60).values[0]
print(f'Probability of being active at 60 months: {survival_60m:.2%}')

# LTV: интеграл от ARPU * S(t) по времени
arpu_per_month = 50 * 0.7  # с маржой
ltv_60m_horizon = arpu_per_month * kmf.survival_function_.cumsum().iloc[-1]
print(f'LTV (60-month horizon): ${ltv_60m_horizon:.0f}')

Плюс — учитывает реальное поведение когорт. Минус — экстраполяция на горизонт, который ты не видел.

На моей практике компромисс — считать LTV на горизонте 36 месяцев. Дольше — слишком много допущений. Короче — слишком мало времени, чтобы увидеть зрелое поведение пользователя.

LTV для разных сегментов

Среднее по компании LTV — почти бесполезная цифра. SMB-клиенты живут 6 месяцев со средним чеком $30. Enterprise — 4 года со средним чеком $5000. Среднее покажет «$800», и оно не отражает ни тех, ни других.

Резать LTV нужно как минимум по:

  • Плану/тарифу.
  • Источнику привлечения (organic / paid / referral).
  • Размеру клиента (для B2B — по числу seats или ARR-band).
  • Гео — особенно если есть валютные различия.

Только в этих разрезах LTV становится цифрой, на которую можно опираться при принятии решений.

Куда деть recurring upgrades

Часть пользователей с временем переходит на более дорогой план. Это улучшает LTV, и его надо учитывать. Но не двойным счётом.

Простой подход — считать monthly_revenue_per_user отдельно для каждого месяца жизни когорты:

SELECT
    cohort_month,
    months_since_signup,
    SUM(monthly_revenue) / cohort_size AS arpu_at_month
FROM ...
GROUP BY 1, 2;

Получаешь ARPU как функцию возраста когорты. Если в N+12 месяцев ARPU выше, чем в N+1 — это net dollar expansion, и он повышает LTV. Простая формула ARPU / churn этого вообще не учитывает.

Связь с CAC

LTV сам по себе не имеет смысла. Имеет смысл только LTV/CAC. Базовый бенчмарк для SaaS — LTV/CAC ≥ 3.

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

Чистый CAC — это Direct CAC, посчитанный только по платному трафику с прозрачным attribution. Organic-клиентов в CAC включать нельзя, иначе ты «удешевляешь» цифру и получаешь нереалистичный LTV/CAC.

Чек-лист перед презентацией LTV

  1. Учтена ли маржинальность? Если нет — цифра завышена в 1.3–2 раза.
  2. Какой горизонт? «Бессрочный» LTV — это ARPU/churn, и он почти всегда оптимистичен.
  3. Резка по сегментам? Среднее без сегментации обычно бесполезно.
  4. Включает ли upsell/downgrade? Если нет — недооценка для зрелых SaaS.
  5. На каких когортах посчитано? Только зрелых или со всеми (с искажением)?
  6. Какой CAC рядом? Direct или Total? Включает ли organic?

Если хотя бы три пункта не выдержаны — цифра LTV не годится для принятия решений о масштабировании. Можно показывать как ориентир, но не как обоснование.

Что забрать с собой

Простая формула ARPU / churn хороша как ментальный ориентир, но плохо работает на реальных данных. Когортный LTV с учётом маржи — это минимум для бизнес-решений. Прогнозный LTV с survival analysis — для продвинутых случаев. Любой LTV без сегментации и без рядом стоящего честного CAC — иллюстрация, не метрика.

Дальше копать стоит в сторону probabilistic LTV (BG/NBD models для contractual settings, Pareto/NBD для non-contractual), и в сторону связи LTV с unit economics: payback period, contribution margin per cohort. Эти штуки отвечают на вопросы, которые годовая LTV-цифра не закрывает.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.