Как посчитать NRR (Net Revenue Retention) в SQL

Проверь себя · 1/3разбор после ответа
В таблице users поле phone бывает NULL и бывает пустой строкой. Какое утверждение верное?

Что такое NRR

NRR (Net Revenue Retention) — метрика SaaS, которая показывает, как изменилась выручка от существующих клиентов за период. В отличие от обычного удержания, NRR считает деньги, а не подписчиков.

NRR > 100% — клиенты в среднем тратят больше, чем год назад. Это сильный сигнал для инвесторов: компания растёт даже без новых клиентов. У топ-SaaS NRR 110-130%.

NRR < 100% — выручка от существующих падает: отток и даунгрейды перевешивают расширение.

На собесе аналитика SaaS NRR — обязательная метрика. Спросят формулу, попросят написать SQL.

Формула

NRR = (Starting MRR + Expansion - Downgrade - Churn) / Starting MRR
  • Starting MRR — выручка когорты на начало периода
  • Expansion — увеличение выручки от тех же клиентов (апгрейды, расширение тарифа)
  • Downgrade — уменьшение тарифа без полного оттока
  • Churn — выручка ушедших клиентов

Период обычно — год (annual NRR) или месяц (monthly NRR).

NRR в разных отраслях

NRR — метрика подписочных бизнесов, но акцент в ней разный.

Enterprise SaaS. Здесь NRR — главная метрика для инвесторов: у сильных компаний она 110–130% за счёт расширения по местам и апселла тарифов. Крупные контракты растут внутри аккаунта, поэтому одно расширение может перекрыть несколько ушедших клиентов.

SMB и self-serve SaaS. NRR обычно ниже (90–105%): мелкие клиенты чаще уходят и реже расширяются, поэтому важнее удержать базу, чем нарастить внутри неё.

Usage-based продукты. NRR естественно выше, потому что выручка растёт с потреблением без явных апгрейдов — клиент просто использует больше. Но она и волатильнее: потребление может падать так же незаметно, как растёт.

SQL: базовый запрос

Допустим, есть таблица subscriptions с MRR клиента по месяцам:

-- subscriptions: customer_id, month, mrr
WITH cohort AS (
  -- Клиенты, которые были активны в стартовом месяце
  SELECT customer_id, mrr AS starting_mrr
  FROM subscriptions
  WHERE month = '2025-05-01'
),
ending AS (
  -- Их MRR ровно через год
  SELECT customer_id, mrr AS ending_mrr
  FROM subscriptions
  WHERE month = '2026-05-01'
)
SELECT
  ROUND(
    SUM(COALESCE(e.ending_mrr, 0))::NUMERIC / NULLIF(SUM(c.starting_mrr), 0),
    3
  ) AS nrr
FROM cohort c
LEFT JOIN ending e USING (customer_id);

Главное — LEFT JOIN, а не INNER. Клиенты, которых нет через год (ушедшие), вернут NULL → COALESCE в 0.

SQL: NRR по когортам

Если хотим NRR за каждый месяц для всех когорт:

WITH monthly_pairs AS (
  SELECT
    s_start.customer_id,
    s_start.month AS cohort_month,
    s_start.mrr AS starting_mrr,
    COALESCE(s_end.mrr, 0) AS ending_mrr
  FROM subscriptions s_start
  LEFT JOIN subscriptions s_end
    ON s_end.customer_id = s_start.customer_id
    AND s_end.month = s_start.month + INTERVAL '1 year'
)
SELECT
  cohort_month,
  COUNT(*) AS customers_in_cohort,
  ROUND(
    SUM(ending_mrr)::NUMERIC / NULLIF(SUM(starting_mrr), 0),
    3
  ) AS nrr
FROM monthly_pairs
GROUP BY cohort_month
ORDER BY cohort_month;

Результат — таблица NRR по каждой когорте. Если у вас стандартная SaaS-таблица с одной строкой на клиента-месяц, эта структура работает напрямую.

Закрепи формулу nrr в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать nrr в Telegram

Что считать «начальной выручкой»

В реальной работе NRR считают на разных видах выручки:

  • Subscription MRR — только подписки
  • Total MRR — подписки + add-ons
  • ARR (annualized) — MRR × 12

Если используете NRR в дашборде для всей компании — берите Total MRR. Если для продуктовой команды — может быть только subscription MRR без услуг.

Примеры с собеседований

NRR на собесе — обязательная метрика для SaaS-аналитика.

«В чём разница NRR и GRR?» Сильный ответ: GRR (Gross Revenue Retention) считает только потери (отток и даунгрейды) и всегда не выше 100%; NRR добавляет расширение и может быть выше 100%. GRR показывает, насколько продукт удерживает базовую выручку, NRR — способен ли он расти внутри существующих клиентов.

«NRR 130% — что это значит и за счёт чего достигается?» Сильный ответ: выручка существующей базы за год выросла на 30% без единого нового клиента — расширение (апгрейды, доп-места, апселл) перекрыло отток и даунгрейды. Это признак сильного продукта с встроенным ростом.

«Почему в NRR нельзя брать новых клиентов периода?» Сильный ответ: NRR измеряет поведение фиксированной когорты, активной на T0. Новые клиенты искусственно раздули бы метрику и смешали удержание с привлечением. Прогнать такие вопросы можно в Карьернике.

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

Использовать INNER JOIN вместо LEFT JOIN. INNER исключит ушедших клиентов, и NRR будет завышен. Это самая частая и дорогая ошибка.

Не учитывать downgrade. Если клиент перешёл с $100/мес на $50/мес — это не отток, но это уменьшение MRR. NRR должен это поймать.

Считать NRR по всем активным, а не по когорте. NRR — про существующих клиентов на момент Т0. Новые клиенты, добавленные за период, в NRR не входят (для них есть GRR/новых).

Делить с integer division. 5 / 20 в Postgres = 0. Кастуйте в NUMERIC или умножайте на 1.0.

Не использовать NULLIF. Если стартовый MRR когорты = 0 (тестовая когорта) — деление на ноль уронит запрос.

Связанные темы

FAQ

NRR vs GRR — в чём разница?

GRR (Gross Revenue Retention) считается по той же логике, но без учёта расширения: GRR = (Starting MRR − Churn − Downgrade) / Starting MRR. Поэтому GRR всегда ≤ 100%, тогда как NRR может превышать 100% за счёт expansion.

Какой NRR считается хорошим?

Для SMB-SaaS нормой считается 90–100%, а 110% — уже хороший результат. У enterprise-SaaS планка выше: 110–130% — это стандарт, а всё, что за 140%, относят к топовым показателям.

Это официальная информация?

Нет. Статья основана на индустриальных практиках SaaS-аналитики и опыте кандидатов.