Коротко: MRR (Monthly Recurring Revenue) — сумма регулярной месячной выручки со всех активных подписок на конкретную дату. Считается как сумма нормализованных к месяцу платежей: годовой тариф делишь на 12, квартальный на 3. ARR — это просто MRR × 12. NRR (Net Revenue Retention) показывает, как изменилась выручка старой когорты клиентов за период БЕЗ учёта новых: NRR = (MRR начала + Expansion − Contraction − Churn) / MRR начала × 100%. NRR выше 100% означает, что бизнес растёт даже если вообще перестанет продавать новым клиентам.
Ниже — три метрики на одном сквозном примере: разложение MRR по компонентам движения, переход к ARR, правильный расчёт NRR и готовые SQL-запросы по таблице подписок.
Что такое MRR и из каких компонентов он состоит?
MRR — это моментальный снимок регулярной выручки. Ключевое слово — «регулярной»: разовые платежи (setup fee, консалтинг, штрафы) в MRR не входят, потому что они не повторяются каждый месяц и портят прогнозируемость.
Главная ловушка новичков — считать MRR как «выручку за месяц по кассе». Это неверно. Если клиент платит 12 000 ₽ за год вперёд, его вклад в MRR — не 12 000 ₽ в месяц оплаты и не 0 ₽ в остальные, а 12000 / 12 = 1000 ₽ каждый месяц действия подписки. MRR нормализует все тарифы к общему знаменателю — одному месяцу.
Нормализация по типам тарифов:
- Месячный тариф 2000 ₽ → вклад в MRR 2000 ₽
- Годовой тариф 21 600 ₽ →
21600 / 12 = 1800 ₽ - Квартальный тариф 5400 ₽ →
5400 / 3 = 1800 ₽ - Разовый платёж 30 000 ₽ → 0 ₽ (не recurring)
Общий MRR на дату — это сумма нормализованных вкладов всех активных подписок. Тесно связанная метрика — ARPU: ARPU = MRR / число активных подписчиков. Если хотите разобраться, чем ARPU отличается от ARPPU, есть отдельный разбор в статье про ARPU и ARPPU.
Как разложить движение MRR на New, Expansion, Contraction, Churn?
Абсолютное значение MRR полезно, но менеджмент и инвесторы смотрят на движение — из чего сложилось изменение между двумя датами. Это называется MRR movement или MRR bridge, и оно раскладывается на пять компонентов.
| Компонент | Что это | Знак |
|---|---|---|
| New MRR | Выручка от клиентов, которых в прошлом периоде не было | + |
| Expansion MRR | Рост по существующим клиентам (апгрейд тарифа, доп. места) | + |
| Reactivation MRR | Вернувшиеся после оттока клиенты | + |
| Contraction MRR | Уменьшение по существующим (даунгрейд, меньше мест) | − |
| Churned MRR | Полностью ушедшие клиенты | − |
Формула моста между периодами:
MRR_конец = MRR_начало + New + Expansion + Reactivation − Contraction − Churned
Пример на числах. Стартовали месяц с MRR = 1 000 000 ₽. За месяц:
- пришли новые клиенты на 150 000 ₽ (New)
- часть старых проапгрейдилась на +80 000 ₽ (Expansion)
- вернулся отвалившийся клиент на 10 000 ₽ (Reactivation)
- кто-то ушёл на тариф ниже, минус 30 000 ₽ (Contraction)
- полностью отвалились клиенты на 120 000 ₽ (Churned)
Считаем: 1 000 000 + 150 000 + 80 000 + 10 000 − 30 000 − 120 000 = 1 090 000 ₽.
Почему это важнее одного числа: два бизнеса могут иметь одинаковый прирост +90 000 ₽, но у первого он держится на бешеном New при огромном Churn (дырявое ведро), а у второго — на здоровом Expansion при почти нулевом оттоке. Второй бизнес намного устойчивее, хотя итоговая цифра совпадает. Отдельно за оттоком стоит следить через churn rate — про его расчёт в SQL есть подробный разбор оттока клиентов.
Как из MRR получить ARR?
Самая простая формула во всей статье: ARR = MRR × 12.
ARR (Annual Recurring Revenue) — годовая версия того же показателя. Её берут, потому что в enterprise-сегменте контракты годовые, а инвесторы мыслят годовыми масштабами: «компания на 24 млн ARR» звучит и сравнивается легче, чем «на 2 млн MRR».
Три важных нюанса, на которых спотыкаются:
- ARR — не сумма кассы за год. Это моментальный MRR, умноженный на 12, то есть годовой run-rate при текущем уровне подписок. Реальная выручка по отчёту о прибылях (GAAP revenue) может отличаться из-за возвратов, скидок и признания выручки по частям.
- Не считайте ARR по разовым платежам. Если в MRR случайно затесались non-recurring суммы, умножение на 12 раздует картину в разы.
- ARR ≠ бронирования (bookings). Подписанный на 3 года контракт даёт bookings на весь срок, но ARR — это годовой срез, а не полная стоимость контракта (TCV).
Для компонентов движения действует то же правило: New ARR = New MRR × 12 и так далее. Аналитику это удобно — декомпозиция один раз считается в месячных величинах, а презентуется в годовых.
Что показывает NRR и как его правильно считать?
NRR (Net Revenue Retention), он же NDR (Net Dollar Retention) — процент выручки, удержанной от когорты существующих клиентов за период, с учётом расширений и оттока, но БЕЗ новых клиентов. Это, пожалуй, главная метрика зрелого SaaS.
Формула:
NRR = (MRR_начало + Expansion − Contraction − Churned) / MRR_начало × 100%
Критично: в числитель НЕ входит New MRR. Мы измеряем судьбу денег, которые уже были у нас в начале периода. Новые клиенты — это отдельная история роста, они не должны маскировать проблемы с удержанием базы.
Пример по нашим числам выше. Берём только старую когорту (без New = 150 000):
NRR = (1 000 000 + 80 000 + 10 000 − 30 000 − 120 000) / 1 000 000 × 100%
= 940 000 / 1 000 000 × 100% = 94%
NRR = 94% означает: если бы мы вообще не продавали новым, выручка от старой базы за месяц сократилась бы на 6%. Рядом полезно держать GRR (Gross Revenue Retention) — то же самое, но без Expansion в числителе:
GRR = (MRR_начало − Contraction − Churned) / MRR_начало × 100%
GRR всегда ≤ NRR и ≤ 100%, потому что не даёт расширениям «замазать» потери. Разрыв между NRR и GRR показывает, насколько сильно апселлы компенсируют отток. NRR тесно связан с retention на уровне пользователей, но считается в деньгах, а не в головах — про пользовательский retention есть отдельная статья про кривую удержания.
Какие нормы NRR считаются здоровыми в 2026 году?
Ориентиры зависят от сегмента, но общая шкала для B2B SaaS выглядит так:
| NRR | Оценка | Типичный сегмент |
|---|---|---|
| < 90% | Проблема: база утекает быстрее, чем растёт | Слабый PMF, высокий отток |
| 90–100% | Нормально для SMB / self-serve | Массовый B2C-подобный SaaS |
| 100–110% | Хорошо: база сама растёт | Крепкий продукт с апселлом |
| 110–125% | Отлично | Зрелый B2B с seat-expansion |
| > 125% | Топ-квартиль | Usage-based pricing, enterprise |
Общие закономерности рынка (обобщённые оценки, не привязанные к конкретному источнику):
- Enterprise обычно держит NRR выше, чем SMB: крупные клиенты реже уходят и чаще докупают места. 110–120% — нормальная планка для сильного enterprise-продукта.
- Self-serve и SMB живут в диапазоне 90–105%: массовый сегмент оттекает активнее.
- Usage-based pricing (платишь за потребление) структурно даёт более высокий NRR, потому что выручка растёт вместе с использованием без явного апселла.
Важнее абсолютного числа — тренд. NRR, стабильно ползущий вниз квартал за кварталом, — ранний сигнал усталости продукта, даже если New MRR пока перекрывает потери. На собеседованиях аналитика этот вопрос любят: если готовитесь, загляните в банк вопросов по метрикам и потренируйте формулировки на AI-собесе.
Как посчитать MRR и NRR SQL-запросом по подпискам?
Возьмём типичную таблицу подписок. Один ряд — одна активная версия подписки с периодом действия и месячной нормализованной ценой.
-- subscriptions
-- subscription_id | customer_id | mrr_amount | started_at | ended_at (NULL = активна)
MRR на конкретную дату — сумма mrr_amount по подпискам, активным на эту дату:
SELECT SUM(mrr_amount) AS mrr
FROM subscriptions
WHERE started_at <= DATE '2026-06-01'
AND (ended_at IS NULL OR ended_at > DATE '2026-06-01');
Теперь декомпозиция движения между двумя месяцами. Считаем MRR каждого клиента на начало и конец периода, а затем классифицируем по компонентам через FULL OUTER JOIN:
WITH start_mrr AS (
SELECT customer_id, SUM(mrr_amount) AS mrr
FROM subscriptions
WHERE started_at <= DATE '2026-05-01'
AND (ended_at IS NULL OR ended_at > DATE '2026-05-01')
GROUP BY customer_id
),
end_mrr AS (
SELECT customer_id, SUM(mrr_amount) AS mrr
FROM subscriptions
WHERE started_at <= DATE '2026-06-01'
AND (ended_at IS NULL OR ended_at > DATE '2026-06-01')
GROUP BY customer_id
),
movement AS (
SELECT
COALESCE(s.customer_id, e.customer_id) AS customer_id,
COALESCE(s.mrr, 0) AS start_mrr,
COALESCE(e.mrr, 0) AS end_mrr
FROM start_mrr s
FULL OUTER JOIN end_mrr e ON s.customer_id = e.customer_id
)
SELECT
SUM(CASE WHEN start_mrr = 0 AND end_mrr > 0
THEN end_mrr END) AS new_mrr,
SUM(CASE WHEN start_mrr > 0 AND end_mrr > start_mrr
THEN end_mrr - start_mrr END) AS expansion_mrr,
SUM(CASE WHEN start_mrr > 0 AND end_mrr < start_mrr AND end_mrr > 0
THEN start_mrr - end_mrr END) AS contraction_mrr,
SUM(CASE WHEN start_mrr > 0 AND end_mrr = 0
THEN start_mrr END) AS churned_mrr,
SUM(start_mrr) AS total_start_mrr,
SUM(end_mrr) AS total_end_mrr
FROM movement;
Из этих агрегатов NRR считается одной строкой поверх результата:
-- NRR = (start + expansion − contraction − churned) / start
SELECT ROUND(
(total_start_mrr + expansion_mrr - contraction_mrr - churned_mrr)
/ total_start_mrr * 100, 1
) AS nrr_pct
FROM (/* подзапрос из декомпозиции выше */) m;
Тот же подход на pandas, если данные лежат в DataFrame, — сгруппировать по клиенту на две даты, сджойнить и классифицировать через numpy.select:
import pandas as pd
import numpy as np
def customer_mrr(df, snapshot):
active = df[(df["started_at"] <= snapshot) &
((df["ended_at"].isna()) | (df["ended_at"] > snapshot))]
return active.groupby("customer_id")["mrr_amount"].sum()
start = customer_mrr(subs, "2026-05-01").rename("start_mrr")
end = customer_mrr(subs, "2026-06-01").rename("end_mrr")
m = pd.concat([start, end], axis=1).fillna(0)
cond = [
(m.start_mrr == 0) & (m.end_mrr > 0),
(m.start_mrr > 0) & (m.end_mrr > m.start_mrr),
(m.start_mrr > 0) & (m.end_mrr < m.start_mrr) & (m.end_mrr > 0),
(m.start_mrr > 0) & (m.end_mrr == 0),
]
m["bucket"] = np.select(cond, ["new", "expansion", "contraction", "churned"],
default="flat")
s = m.start_mrr.sum()
expansion = (m.end_mrr - m.start_mrr).where(m.bucket == "expansion", 0).sum()
contraction = (m.start_mrr - m.end_mrr).where(m.bucket == "contraction", 0).sum()
churned = m.start_mrr.where(m.bucket == "churned", 0).sum()
nrr = (s + expansion - contraction - churned) / s * 100
print(round(nrr, 1))
Разобрать оба запроса построчно и покрутить их на живых данных удобнее в SQL-тренажёре и Python-тренажёре — там настоящий PostgreSQL и Pyodide прямо в браузере. Если window-функции и FULL OUTER JOIN пока в новинку, начните с базового курса SQL.
Какие ошибки чаще всего искажают MRR и NRR?
Даже с правильными формулами цифры легко испортить на этапе подготовки данных. Вот типичные грабли, на которые наступают аналитики.
- Разовые платежи в MRR. Setup fee, оплата за внедрение, разовый консалтинг попадают в регулярную выручку — и MRR раздувается. Фильтруйте по типу платежа ещё до агрегации.
- Двойной счёт при смене тарифа. Если апгрейд оформлен как новая подписка, а старая не закрыта, клиент задваивается. Проверяйте, что на дату среза у клиента ровно одна активная запись.
- Налоги и скидки не нормализованы. MRR считают по net-выручке после скидок и без НДС. Смешение gross и net ломает сопоставимость между когортами.
- Валюта не приведена к одной. В мультивалютном бизнесе складывать рубли, тенге и доллары напрямую нельзя — конвертируйте по фиксированному курсу на дату среза, иначе движение MRR будет отражать курс, а не бизнес.
- New затесался в NRR. Самая частая ошибка в расчёте удержания: новые клиенты попадают в числитель и завышают NRR. В декомпозиции выше это отсекается условием
start_mrr = 0. - Годовые контракты не разнесены помесячно. Если весь годовой платёж посадить в месяц оплаты, MRR будет скакать пилой. Всегда делите на срок действия.
Дисциплина на этапе очистки данных важнее красоты формулы: почти все расхождения в MRR-отчётах — это не математика, а грязный источник. Потренировать типовые запросы на чистку и агрегацию можно в тренажёре, а разобрать смежные подводные камни — в статье про антипаттерны SQL.
Почему NRR выше 100% означает рост без новых клиентов?
Разберём на пределе. Представьте, что маркетинг остановлен: ни одного нового клиента. Что произойдёт с выручкой?
Ответ полностью определяется NRR. При NRR = 100% выручка стоит на месте — расширения ровно компенсируют отток. При NRR = 115% выручка растёт на 15% за период сама собой: существующие клиенты докупают места и апгрейдят тарифы быстрее, чем уходят их соседи по когорте.
Это свойство делает NRR > 100% «святым Граалем» SaaS. Такой бизнес обладает встроенным маховиком роста: даже при полной остановке привлечения выручка увеличивается. А каждый рубль, потраченный на New, ложится сверху уже растущей базы, а не латает дыры оттока.
Простая иллюстрация накопления при NRR = 115% и нулевом New:
- Месяц 0: 1 000 000 ₽
- Месяц 1:
1 000 000 × 1.15 = 1 150 000 ₽ - Месяц 2:
1 150 000 × 1.15 = 1 322 500 ₽
Именно поэтому NRR — сильнейший предиктор долгосрочной стоимости компании и один из главных драйверов LTV. Высокий NRR удлиняет жизнь клиента и увеличивает выручку с него, что напрямую улучшает юнит-экономику. Как NRR встраивается в LTV/CAC/payback, детально разобрано в материале по unit-экономике SaaS, а базовые понятия CM1/CM2 — в статье про юнит-экономику простыми словами.
Что стоит унести с собой:
- MRR — моментальный снимок регулярной выручки, нормализованной к месяцу. Разовые платежи не считаем.
- Декомпозиция New / Expansion / Contraction / Churn важнее одного числа — она показывает качество роста.
- ARR = MRR × 12 — тот же показатель в годовом run-rate, не путать с кассой и bookings.
- NRR меряет судьбу старой когорты в деньгах, без новых клиентов; здоровый диапазон в 2026 — от 100% и выше.
- NRR > 100% = встроенный рост выручки даже без привлечения.
Лучший способ закрепить — написать декомпозицию MRR своими руками по реальной таблице подписок. Первые 5 задач в тренажёре открыты бесплатно, дальше доступ по Pro. Соберёте MRR-bridge и NRR за один вечер — и на собеседовании этот блок вопросов уже не застанет врасплох.