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