SaaS Churn Analysis Skill
Deep-dive churn and retention analysis for SaaS businesses. Build cohort tables, calculate NRR/GRR, identify at-risk accounts, and produce investor-ready retention metrics with actionable recovery playbooks.
When to Use This Skill
Trigger phrases:
- - "Why are customers churning?"
- "What's our retention rate?"
- "Build a cohort analysis"
- "Show me net revenue retention"
- "Which accounts are at risk of canceling?"
- "Investor wants to see our logo churn"
- "What's our gross/net dollar retention?"
- "Analyze our expansion vs contraction MRR"
NOT for:
- - Executing recovery outreach (emails, calls) — use CRM/email tools
- Billing changes, refunds, or cancellation processing — use billing platform
- General MRR tracking — use
saas-metrics-dashboard or INLINECODE1 - Revenue forecasting — use INLINECODE2
- Customer success management — use a CS platform skill
Core Churn Definitions
Logo Churn (Customer Churn)
CODEBLOCK0
Revenue Churn
CODEBLOCK1
Net Revenue Retention (NRR / NDR)
CODEBLOCK2
NRR Benchmarks (SaaS industry):
| NRR | Signal |
|---|
| >120% | Elite (enterprise, product-led) |
| 110–120% |
Strong — expansion > churn |
| 100–110% | Healthy |
| 90–100% | Adequate — watch churn trends |
| <90% | Red flag — structural problem |
Gross Revenue Retention (GRR)
GRR = (Beginning MRR - Contraction MRR - Churned MRR) / Beginning MRR × 100
(excludes expansion — pure retention, no upsell credit)
Healthy GRR benchmarks:
Enterprise SaaS: >90%
Mid-market: >85%
SMB SaaS: >75%
Cohort Analysis
Building a Cohort Retention Table
Track customers by their acquisition month and measure % remaining in each subsequent month:
CODEBLOCK4
Example cohort table output:
CODEBLOCK5
Revenue Cohort (Dollar Retention)
Track MRR retained and expanded per cohort:
CODEBLOCK6
Churn Curve Analysis
Identify when in the customer lifecycle churn peaks:
CODEBLOCK7
Churn by tenure bucket:
def churn_by_tenure(subscriptions_df: pd.DataFrame) -> dict:
"""Calculate churn rate for different tenure buckets."""
buckets = {
'0-3mo': (0, 90),
'3-6mo': (90, 180),
'6-12mo': (180, 365),
'12-24mo': (365, 730),
'24mo+': (730, float('inf'))
}
results = {}
for bucket_name, (min_days, max_days) in buckets.items():
mask = (
(subscriptions_df['tenure_days'] >= min_days) &
(subscriptions_df['tenure_days'] < max_days)
)
bucket_df = subscriptions_df[mask]
if len(bucket_df) == 0:
continue
churned = bucket_df[bucket_df['cancel_date'].notna()].shape[0]
results[bucket_name] = {
'total_customers': len(bucket_df),
'churned': churned,
'churn_rate_pct': round(churned / len(bucket_df) * 100, 1)
}
return results
At-Risk Customer Identification
Churn Risk Scoring
Score each active customer by leading indicators:
CODEBLOCK9
Early Warning Signals
Usage-based signals (product telemetry):
CODEBLOCK10
Financial signals:
🔴 High risk:
- Payment failure (retry in progress)
- Requested invoice-based payment shift (budget freeze)
- Contract not opened with 30 days to renewal
🟡 Medium risk:
- Asked about pricing alternatives
- Billing contact changed
- Discount request submitted
MRR Movement Analysis
MRR Bridge
Decompose monthly MRR change into components:
CODEBLOCK12
Python MRR bridge calculation:
CODEBLOCK13
SaaS Quick Ratio benchmarks:
| Quick Ratio | Signal |
|---|
| >4 | Elite growth efficiency |
| 2–4 |
Healthy |
| 1–2 | Growing but inefficient — churn drag |
| <1 | Shrinking — churn exceeds new + expansion |
Churn Recovery Playbooks
Playbook 1: Early Churn (Month 1-3)
Root cause: Failed onboarding, didn't reach first value moment
Diagnosis questions:
CODEBLOCK14
Recovery actions:
CODEBLOCK15
Playbook 2: Mid-Term Churn (Month 4-12)
Root cause: Value plateau, competitive evaluation, budget pressure
Diagnosis questions:
CODEBLOCK16
Recovery actions by root cause:
CODEBLOCK17
Playbook 3: Renewal-at-Risk (30-60 days to renewal)
Proactive renewal pipeline:
60 days out:
□ Usage review: send personalized "Your results with [Product]" email
□ Identify any open issues — resolve before renewal conversation
45 days out:
□ QBR or check-in call — confirm value, surface upsell opportunity
□ Flag to AE if NPS < 7 or usage declining
30 days out:
□ Renewal proposal sent — include current plan + upsell option
□ Executive sponsor confirmation (for accounts >$1k/mo)
14 days out:
□ Follow-up if no response — switch to phone
□ Escalate to manager if no reply
7 days out:
□ Final decision call — accept reduced terms if needed to retain
Output Formats
Investor-Ready Retention Summary
CODEBLOCK19
CSV Export for Spreadsheets
CODEBLOCK20
Step-by-Step Workflow
Full Churn Audit
Step 1: Data collection
CODEBLOCK21
Step 2: Calculate headline metrics
- - Logo churn rate (monthly and annualized)
- Gross and net revenue retention
- Quick ratio
- Churn by tenure bucket
Step 3: Build cohort table
- - M0–M12 retention by acquisition cohort
- Identify best and worst cohorts — find what's different
Step 4: MRR bridge (last 6 months)
- - New vs expansion vs contraction vs churn
- Trend analysis: is churn improving or worsening?
Step 5: At-risk identification
- - Score all active customers by churn risk signals
- Prioritize by MRR at risk (highest first)
- Output: top 10 at-risk accounts with reasons
Step 6: Root cause analysis
- - What's driving churn? (onboarding failure, competition, budget, product gaps)
- Which segments have highest churn? (plan size, industry, use case, acquisition channel)
Step 7: Recommend playbook
- - Match root cause to recovery playbook
- Estimate MRR at stake if intervention succeeds (recovery potential)
- Prioritize actions by expected ROI
Churn by Segment Analysis
Segment churn to find structural patterns:
CODEBLOCK22
Key segments to analyze:
- - By plan tier (free trial → paid → enterprise)
- By acquisition channel (organic, paid, referral)
- By company size (SMB, mid-market, enterprise)
- By industry vertical
- By geographic region
- By sales rep / CSM (is one rep's book churning faster?)
Integration Points
- -
saas-metrics-dashboard — Display NRR, GRR, and churn rate KPIs in dashboard kpi-alert-system — Trigger alerts when monthly churn exceeds thresholdstartup-financial-model — Feed churn rate assumptions into revenue forecastssubscription-revenue-tracker — MRR bridge data source for churn calculationscrypto-tax-agent — N/A (different domain)
Key Formulas Cheat Sheet
CODEBLOCK23
SaaS 流失分析技能
面向SaaS业务的深度流失与留存分析。构建群组表,计算NRR/GRR,识别高风险账户,并生成投资者级别的留存指标及可执行的挽回方案。
何时使用该技能
触发短语:
- - 为什么客户在流失?
- 我们的留存率是多少?
- 构建一个群组分析
- 展示净收入留存
- 哪些账户有取消风险?
- 投资者想查看我们的客户流失情况
- 我们的总/净美元留存率是多少?
- 分析我们的扩张与收缩MRR
不适用于:
- - 执行挽回触达(邮件、电话)——使用CRM/邮件工具
- 账单变更、退款或取消处理——使用计费平台
- 常规MRR追踪——使用saas-metrics-dashboard或subscription-revenue-tracker
- 收入预测——使用startup-financial-model
- 客户成功管理——使用CS平台技能
核心流失定义
客户流失(Logo Churn)
客户流失率(月度)= 流失客户数 / 期初客户数
示例:
月初:200个客户
取消:5个
客户流失率:5/200 = 2.5%
收入流失(Revenue Churn)
总收入流失率 = 取消导致的MRR损失 / 期初MRR
示例:
期初MRR:$100,000
流失MRR:$4,000(来自取消)
总流失率:4%
净收入留存(NRR / NDR)
NRR =(期初MRR + 扩张MRR - 收缩MRR - 流失MRR)/ 期初MRR × 100
组成部分:
+ 扩张MRR:现有客户的追加销售、升级、增加席位
- 收缩MRR:降级、减少席位
- 流失MRR:取消
示例:
期初MRR:$100,000
扩张:+$8,000
收缩:-$2,000
流失:-$4,000
NRR =($100,000 + $8,000 - $2,000 - $4,000)/ $100,000 = 102%
NRR基准(SaaS行业):
| NRR | 信号 |
|---|
| >120% | 精英级(企业级、产品驱动) |
| 110–120% |
强劲——扩张 > 流失 |
| 100–110% | 健康 |
| 90–100% | 尚可——关注流失趋势 |
| <90% | 危险信号——结构性问题 |
总收入留存(GRR)
GRR =(期初MRR - 收缩MRR - 流失MRR)/ 期初MRR × 100
(排除扩张——纯留存,无追加销售加分)
健康GRR基准:
企业级SaaS:>90%
中端市场:>85%
SMB SaaS:>75%
群组分析
构建留存群组表
按客户的获取月份进行追踪,并衡量后续每个月的留存百分比:
python
import pandas as pd
from datetime import datetime
def buildcohorttable(subscriptions_df: pd.DataFrame) -> pd.DataFrame:
从订阅数据构建留存群组表。
输入DataFrame列:
- customer_id: str
- signup_date: datetime
- cancel_date: datetime | None(None = 仍活跃)
返回:
透视表:行 = 群组月份,列 = 注册后月数,
值 = 留存百分比
df = subscriptions_df.copy()
df[cohortmonth] = df[signupdate].dt.to_period(M)
df[activethrough] = df[canceldate].fillna(pd.Timestamp.now())
rows = []
for cohort, group in df.groupby(cohort_month):
cohort_size = len(group)
for month_offset in range(0, 25): # 0–24个月
cutoff = cohort.totimestamp() + pd.DateOffset(months=monthoffset)
active = group[group[active_through] >= cutoff].shape[0]
retention = active / cohort_size * 100
rows.append({
cohort: str(cohort),
month: month_offset,
cohortsize: cohortsize,
active: active,
retention_pct: round(retention, 1)
})
result = pd.DataFrame(rows)
pivot = result.pivot(index=cohort, columns=month, values=retention_pct)
return pivot
示例群组表输出:
群组 | M0 | M1 | M3 | M6 | M12
-----------|-------|-------|-------|-------|------
2025-01 | 100% | 91% | 81% | 72% | 58%
2025-02 | 100% | 93% | 84% | 76% | —
2025-03 | 100% | 89% | 79% | — | —
2025-04 | 100% | 94% | — | — | —
收入群组(美元留存)
追踪每个群组的MRR留存和扩张:
python
def revenuecohorttable(mrreventsdf: pd.DataFrame) -> pd.DataFrame:
收入群组分析,追踪每个获取群组的MRR。
输入DataFrame列:
- customer_id: str
- event_date: datetime
- event_type: str # signup, expansion, contraction, churn
- mrr_change: float
返回:
群组收入留存表(原始MRR留存+扩张的百分比)
# 按注册群组分组
signups = mrreventsdf[mrreventsdf[event_type] == signup].copy()
signups[cohortmonth] = signups[eventdate].dt.to_period(M)
# 对于每个群组,随时间追踪MRR
# 按群组的NRR = 群组客户所有MRR变化之和 / 初始MRR
pass
流失曲线分析
识别客户生命周期中流失的高峰期:
早期流失(M1-M3):入职失败,未交付价值
→ 诊断:激活率、首次价值实现时间、支持工单
中期流失(M4-M12):竞争替代、预算削减
→ 诊断:NPS趋势、功能采用、续约参与度
晚期流失(M12+):战略转变、合同条款、企业竞争
→ 诊断:高管发起人变更、使用趋势、续约对话
按任期分组的流失:
python
def churnbytenure(subscriptions_df: pd.DataFrame) -> dict:
计算不同任期分组的流失率。
buckets = {
0-3个月: (0, 90),
3-6个月: (90, 180),
6-12个月: (180, 365),
12-24个月: (365, 730),
24个月+: (730, float(inf))
}
results = {}
for bucketname, (mindays, max_days) in buckets.items():
mask = (
(subscriptionsdf[tenuredays] >= min_days) &
(subscriptionsdf[tenuredays] < max_days)
)
bucketdf = subscriptionsdf[mask]
if len(bucket_df) == 0:
continue
churned = bucketdf[bucketdf[cancel_date].notna()].shape[0]
results[bucket_name] = {
totalcustomers: len(bucketdf),
churned: churned,
churnratepct: round(churned / len(bucket_df) * 100, 1)
}
return results
高风险客户识别
流失风险评分
根据领先指标对每个活跃客户进行评分:
python
CHURNRISKWEIGHTS = {
dayssincelast_login: 0.25, # 使用下降
featureadoptionpct: -0.20, # 反向:更多功能 = 更低风险
supporttickets30d: 0.15, # 升级
nps_score: -0.15, # 反向:高NPS = 更低风险
daystorenewal: -0.10, # 续约越近 = 越紧急
billingfailures90d: 0.15, # 支付问题
}
def churnriskscore(customer: dict) -> float:
计算客户0-100的