Как посчитать expansion MRR в SQL
Содержание:
Зачем expansion MRR
Expansion MRR — рост платы от существующих customers через upgrade плана или добавление seats. В отличие от new MRR (новые клиенты), expansion дёшев в acquisition: уже привлечённый customer покупает больше. Healthy SaaS получает 30-50% всего нового revenue из expansion.
Что считать expansion
3 типа:
- Plan upgrade: Basic → Premium
- Seat expansion: 10 → 15 users
- Usage-based growth: больше API calls / GB / events
В SQL обычно сравнивают MRR клиента на конец vs начало периода (если вырос — 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) отсекает new customers (нет на старте) и churned (нет на конце).
По типу expansion
Разделить plan upgrade от seat 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 для full picture:
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 на churned. Если customer churned и снова signup с большим MRR — это не expansion, это win-back + new.
Ошибка 2. Использовать posted invoice вместо subscription state. Annual prepay создаст «expansion» в месяц оплаты. Нужен MRR на нормализованной шкале.
Ошибка 3. Path: A → B → A в одном периоде. Customer downgraded потом upgraded back — выглядит как «no change». В детальной аналитике важно фиксировать оба события.
Ошибка 4. Игнорировать pricing changes. Если вы повысили цены, MRR существующих вырос — это «pricing expansion», not voluntary upgrade.
Ошибка 5. Average expansion на base. Average expansion per customer = total_expansion / total customers даст низкое число. Полезнее AVG только on expanding.
Связанные темы
- Как посчитать contraction MRR в SQL
- Как посчитать MRR в SQL
- Как посчитать net dollar retention в SQL
- Как посчитать upgrade rate в SQL
FAQ
Какая доля expansion — норма?
30-50% всего нового MRR. У PLG-моделей бывает 60%+.
Expansion vs upsell?
Синонимы. Upsell — sales-термин, expansion — аналитический.
Можно ли отрицательный expansion?
Нет. Отрицательное движение — это contraction, отдельная метрика.
Quick ratio с expansion?
Quick Ratio = (new + expansion) / (contraction + churn). Чем выше — тем лучше.
Можно ли в Postgres без сложных CTE?
В простой версии да — start vs end MRR. Расширенный split нужны snapshot таблицы.