Как посчитать expansion MRR в SQL
events_web и events_app, чтобы посчитать количество событий. Важно не потерять повторяющиеся события (например, два одинаковых клика). Что лучше использовать для объединения?Содержание:
Зачем expansion MRR
Expansion MRR — рост платы от существующих клиентов за счёт перехода на более дорогой план или добавления мест (seats). В отличие от new MRR (новые клиенты), expansion дёшев в привлечении: уже привлечённый клиент просто покупает больше. Здоровый SaaS получает 30–50% всей новой выручки именно из expansion.
Что считать expansion
3 типа:
- Апгрейд плана: Basic → Premium
- Расширение по местам (seats): 10 → 15 пользователей
- Рост потребления: больше API-вызовов / GB / событий
В SQL обычно сравнивают MRR клиента на конце и на начале периода: если вырос — это expansion.
Expansion в SQL
WITH start_mrr AS (
SELECT customer_id, mrr AS start_mrr
FROM subscription_state
WHERE state_date = '2026-04-01' AND status = 'active'
),
end_mrr AS (
SELECT customer_id, mrr AS end_mrr
FROM subscription_state
WHERE state_date = '2026-05-01' AND status = 'active'
),
both AS (
SELECT
s.customer_id,
s.start_mrr,
e.end_mrr,
GREATEST(0, e.end_mrr - s.start_mrr) AS expansion
FROM start_mrr s
JOIN end_mrr e USING (customer_id)
)
SELECT
SUM(expansion) AS total_expansion_mrr,
COUNT(*) FILTER (WHERE expansion > 0) AS expanding_customers,
AVG(expansion) FILTER (WHERE expansion > 0) AS avg_expansion_per_customer
FROM both;JOIN ... USING (customer_id) отсекает новых клиентов (их нет на старте) и ушедших в отток (их нет на конце).
По типу expansion
Разделить апгрейд плана и расширение по местам:
WITH state_change AS (
SELECT
customer_id,
plan_at_start,
plan_at_end,
seats_at_start,
seats_at_end,
mrr_at_start,
mrr_at_end,
CASE
WHEN plan_at_end <> plan_at_start AND mrr_at_end > mrr_at_start THEN 'plan_upgrade'
WHEN seats_at_end > seats_at_start AND plan_at_end = plan_at_start THEN 'seat_expansion'
WHEN mrr_at_end > mrr_at_start THEN 'usage_growth'
ELSE 'no_expansion'
END AS expansion_type
FROM monthly_customer_snapshot
WHERE snapshot_month = '2026-04-01'
)
SELECT
expansion_type,
COUNT(*) AS customers,
SUM(mrr_at_end - mrr_at_start) AS expansion_mrr
FROM state_change
WHERE mrr_at_end > mrr_at_start
GROUP BY expansion_type
ORDER BY expansion_mrr DESC;Net new MRR
Объединить с новыми продажами (new business) и contraction, чтобы получить полную картину:
SELECT
'new_mrr' AS source,
SUM(mrr) AS amount
FROM subscriptions
WHERE created_at >= '2026-04-01' AND created_at < '2026-05-01'
UNION ALL
SELECT
'expansion',
SUM(expansion)
FROM both
WHERE expansion > 0
UNION ALL
SELECT
'contraction',
-SUM(s.start_mrr - COALESCE(e.end_mrr, 0))
FROM start_mrr s
LEFT JOIN end_mrr e USING (customer_id)
WHERE COALESCE(e.end_mrr, 0) < s.start_mrr AND e.end_mrr > 0
UNION ALL
SELECT
'churned',
-SUM(s.start_mrr)
FROM start_mrr s
LEFT JOIN end_mrr e USING (customer_id)
WHERE e.end_mrr IS NULL OR e.end_mrr = 0;Сумма всех четырёх строк = net new MRR за месяц.
Частые ошибки
Ошибка 1. Считать expansion на ушедших в отток. Если клиент ушёл в отток, а потом снова подписался с бо́льшим MRR — это не expansion, а win-back плюс new.
Ошибка 2. Использовать выставленный счёт вместо состояния подписки. Годовая предоплата создаст «expansion» в месяц оплаты. Нужен MRR на нормализованной помесячной шкале.
Ошибка 3. Путь A → B → A в одном периоде. Клиент понизил план, а потом вернулся на прежний — выглядит как «без изменений». В детальной аналитике важно зафиксировать оба события.
Ошибка 4. Игнорировать изменения цен. Если вы подняли цены, MRR существующих клиентов вырос — но это «pricing expansion», а не добровольный апгрейд.
Ошибка 5. Средний expansion по всей базе. Средний expansion на клиента = total_expansion / все клиенты даст заниженное число. Полезнее брать среднее только по тем, кто реально расширился.
Связанные темы
- Как посчитать contraction MRR в SQL
- Как посчитать MRR в SQL
- Как посчитать net dollar retention в SQL
- Как посчитать upgrade rate в SQL
FAQ
Какая доля expansion — норма?
Ориентир — 30–50% всего нового MRR. У продуктов с product-led growth (PLG) эта доля бывает и 60%+: продукт продаёт сам себя, и клиенты растут внутри без участия продавцов.
Expansion vs upsell?
По сути это про одно и то же. Upsell — термин из мира продаж (продать существующему клиенту больше), а expansion — его аналитическое отражение в метриках MRR. Разница только в том, с какой стороны вы на это смотрите.
Можно ли отрицательный expansion?
Нет, expansion по определению неотрицателен. Если MRR клиента уменьшился, это уже contraction — отдельная метрика, которую считают и трактуют иначе.
Quick ratio с expansion?
Quick Ratio показывает, насколько рост перекрывает потери: Quick Ratio = (new + expansion) / (contraction + churn). Чем выше значение, тем здоровее рост: единица означает, что вы лишь компенсируете отток, а всё, что выше, — это уже чистый рост.
Можно ли в Postgres без сложных CTE?
В простом виде — да: достаточно сравнить MRR на начало и на конец периода. Но для детального разбиения по типам expansion уже нужны snapshot-таблицы с состоянием подписок на каждую дату.