agnes-the-ai-analyst/docs/metrics/revenue/churn_rate.yml

48 lines
1.5 KiB
YAML

name: churn_rate
display_name: Monthly Churn Rate
category: revenue
type: ratio
unit: percentage
grain: monthly
table: subscriptions
expression: "churned_mrr / beginning_mrr * 100"
time_column: billing_date
description: "Monthly revenue churn rate — the percentage of MRR lost due to cancellations and downgrades in a given month."
dimensions:
- plan_type
- region
synonyms:
- mrr_churn
- revenue_churn
- monthly_churn
notes:
- "Revenue churn differs from customer churn — one large customer churning can dominate"
- "Negative churn occurs when expansion revenue exceeds lost revenue"
- "Target: <2% monthly for healthy SaaS businesses"
- "Churned MRR includes full cancellations and partial downgrades"
sql: |
WITH monthly_mrr AS (
SELECT
DATE_TRUNC('month', billing_date) AS month,
SUM(CASE WHEN status = 'active' THEN mrr_amount ELSE 0 END) AS active_mrr,
SUM(CASE WHEN status = 'churned'
AND DATE_TRUNC('month', churned_at) = DATE_TRUNC('month', billing_date)
THEN mrr_amount ELSE 0 END) AS churned_mrr
FROM subscriptions
GROUP BY 1
),
lagged AS (
SELECT
month,
churned_mrr,
LAG(active_mrr) OVER (ORDER BY month) AS beginning_mrr
FROM monthly_mrr
)
SELECT
month,
churned_mrr,
beginning_mrr,
ROUND(churned_mrr / NULLIF(beginning_mrr, 0) * 100, 2) AS churn_rate_pct
FROM lagged
WHERE beginning_mrr IS NOT NULL
ORDER BY month