Как посчитать Gross Dollar Retention в SQL
Зачем GDR
Gross Dollar Retention (GDR) — «чистая» удержка выручки без expansion. Если NDR 120% за счёт upgrades скрывает плохой product-market fit для базы, GDR показывает истину: «сколько $$ из start MRR мы сохранили?». Используется в борде SaaS-фондов как baseline здоровья.
Формула
GDR = (start_MRR − contraction − churn) / start_MRRExpansion НЕ входит. GDR ≤ 100% всегда (максимум — никто не отвалился и не даунгрейднул).
GDR в SQL
WITH start_cohort AS (
SELECT customer_id, mrr AS start_mrr
FROM subscription_state
WHERE state_date = '2025-05-01' AND status = 'active'
),
end_state AS (
SELECT customer_id, mrr AS end_mrr
FROM subscription_state
WHERE state_date = '2026-05-01'
),
joined AS (
SELECT
s.customer_id,
s.start_mrr,
COALESCE(e.end_mrr, 0) AS end_mrr,
LEAST(s.start_mrr, COALESCE(e.end_mrr, 0)) AS retained_mrr
FROM start_cohort s
LEFT JOIN end_state e USING (customer_id)
)
SELECT
SUM(start_mrr) AS total_start_mrr,
SUM(retained_mrr) AS total_retained_mrr,
SUM(retained_mrr)::NUMERIC * 100 / NULLIF(SUM(start_mrr), 0) AS gdr_pct
FROM joined;Трюк LEAST(start_mrr, end_mrr) — отрезает expansion (берём min). Если customer вырос с $100 до $200, retained = $100; если упал с $100 до $50, retained = $50.
GDR vs NDR
SELECT
SUM(start_mrr) AS start_mrr,
-- GDR: без expansion
SUM(LEAST(start_mrr, COALESCE(end_mrr, 0)))::NUMERIC * 100 / NULLIF(SUM(start_mrr), 0) AS gdr_pct,
-- NDR: с expansion
SUM(COALESCE(end_mrr, 0))::NUMERIC * 100 / NULLIF(SUM(start_mrr), 0) AS ndr_pct,
-- Разница = expansion contribution
(SUM(COALESCE(end_mrr, 0)) - SUM(LEAST(start_mrr, COALESCE(end_mrr, 0))))::NUMERIC
* 100 / NULLIF(SUM(start_mrr), 0) AS expansion_contribution_pct
FROM joined;NDR 120% + GDR 85% — модель «expansion лечит churn». Healthy: NDR > 110%, GDR > 90%.
По сегментам
Enterprise vs SMB:
SELECT
plan_segment,
SUM(start_mrr) AS start_mrr,
SUM(LEAST(start_mrr, COALESCE(end_mrr, 0)))::NUMERIC * 100
/ NULLIF(SUM(start_mrr), 0) AS gdr_pct
FROM joined
GROUP BY plan_segment;Enterprise GDR 95-98% (стабильно), SMB 80-90% (волатильно).
Частые ошибки
Ошибка 1. Считать GDR с expansion. GDR by definition без upside. Если случайно включили — это NDR.
Ошибка 2. LEAST в неправильном порядке.
LEAST(start, end) отрезает рост. GREATEST дал бы expansion-only — это другая метрика.
Ошибка 3. Игнорировать downgrade в одном subscription.
subscription_state должен учитывать current MRR, не historical price. Иначе downgrades скрыты.
Ошибка 4. GDR + Churn rate != 100%. GDR — про доллары, churn rate — про customers. Не суммируются.
Ошибка 5. GDR на коротком периоде. Месяц GDR может быть 99% просто потому что мало кто отвалился. 12-month GDR — стандарт.
Связанные темы
- Как посчитать net dollar retention в SQL
- Как посчитать MRR churn в SQL
- Как посчитать MRR в SQL
- Как посчитать contraction MRR в SQL
FAQ
GDR vs NDR — что важнее?
NDR показывает рост, GDR — здоровье базы. Смотрят оба.
GDR может быть > 100%?
Нет — по определению ≤ 100%.
Какой GDR хороший?
Enterprise: 95%+. SMB: 85%+.
Как чинить низкий GDR?
Сначала — root cause: churn vs downgrade. Cancellation interviews, downgrade analytics.
GDR на годовой контракт?
Аналогично: start ARR, end ARR. Главное — фиксируйте период.