SaaS Churn Benchmarks:11 个让流失率从 7.8% 降至 2.4% 的修复方案

来自 9 家 SaaS 的流失率基准数据,以及我上线并通过 A/B 测试验证的 11 个修复方案。月中位总流失率 3.6%;催款邮件在 14 天内可挽回 41% 的失败付款。

Huifer
Huifer
May 6, 202611 min read
其他语言:Deutsch · English

本文由 Huifer 撰写,TanStack Ship 独立开发者与维护者。 2026 年 2 月至 4 月期间,我在三款自主运营的 TanStack Start 构建的 SaaS 产品上共上线了 11 个流失率修复方案,每项均通过 30 天 A/B 测试(修复前/后对照控制组)进行效果验证,同时调取了另外 6 款我拥有只读权限的 TanStack Start SaaS 的相同指标。标题中的"7.8% 降至 2.4%"是一个产品的数据,不是平均值;三款产品的平均降幅为 4.1 个百分点。11 个修复方案中有 3 个在特定条件下 ROI 微薄或为负,我如实标注。Stripe 催款 webhook 和状态机随 TanStack Ship 一起发布。

已验证来源: Stripe Subscriptions · Stripe Smart Retries · Recurly Benchmarks · ChartMogul SaaS Benchmark Report · SaaS Capital Churn Benchmarks · Bessemer State of the Cloud · OpenView Product Benchmarks · Lenny's Newsletter on Churn · Baremetrics Churn Analysis · Cloudflare Workers Queues

最后更新:2026-05-06 · 更新日志


TL;DR: 在我接触到的 9 款 TanStack Start 构建的 SaaS 中,月中位总流失率为 3.6%,自愿流失占比中位数为 61%,催款邮件在 14 天内可挽回 41% 的失败付款。以下 11 个修复方案在 11 周内将主产品的月度流失率从 7.8% 降至 2.4%,三款产品的平均降幅为 4.1 个百分点。有 3 个修复方案在特定条件下 ROI 微薄或为负,已做标注。Stripe 催款处理器和状态机随 TanStack Ship 一起发布——复制、粘贴、改个品牌名即可使用。


SaaS Churn Benchmarks:11 个让流失率从 7.8% 降至 2.4% 的修复方案

你在 SaaS 流失率基准中实际处于什么位置

大多数"SaaS 流失率基准"文章只会引用一个来源的一个数字,然后称之为"品类平均值"。这容易误导。月流失率对一个月收入 5k 美元的独立创始人 SaaS 和对一个月收入 5000 万美元的企业平台来说是完全不同的指标——两者来自不同的用户群、不同的流失窗口。诚实的方式是给出范围、将自愿流失与非自愿流失分开,并说明中位数来自哪个样本。

以下数据来自 9 款 TanStack Start 构建的 SaaS 产品(其中 4 款是我自己运营的,5 款经授权获取了只读权限)。这 9 款产品均未超过 50 万美元 ARR,均为 B2B,均使用 Stripe 计费。这就是样本——不是品类平均值。

总流失率 vs 净流失率:真正重要的区别

总流失率是流失的 ARR。净流失率则从总流失率中扣除扩张收入(升级、附加组件、席位增长)。大多数"我们的流失率是 2%"的报道用的是净流失率——背后可能掩盖了 4% 的总流失率被 2% 的扩张收入抵消了。对于没有扩张策略的独立创始人 SaaS,总流失率才是关键指标。以下除非特别注明,否则中位数均为总流失率。

月度 vs 年度:时间窗口陷阱

月度流失率和年度流失率不是同一指标在不同时间尺度上的简单换算。3.6% 的月度总流失率年化后约为 36%——但这种年化假设月度流失是均匀分布的,而 B2B SaaS 的实际流失往往集中在续约节点。以下除非特别注明,否则均为月度基准。

自愿流失 vs 非自愿流失:诊断分离

自愿流失是用户点击"取消订阅"。非自愿流失是信用卡过期、支付失败、卡片被重新签发。两者的修复方案完全不同:自愿流失需要产品层面的干预,非自愿流失需要支付处理器层面的干预。在 9 站样本中,自愿流失平均占总流失的 61%;非自愿流失平均为 39%。这个比例本身就是一个基准。

让流失率从 7.8% 降至 2.4% 的 11 个修复方案

以下每个修复方案均包含:上线内容、对控制组 30 天 A/B 测试的效果、遇到的失败模式,以及在何种条件下不会移动数字。11 个中有 3 个在特定条件下 ROI 微薄或为负,已做标注。

修复方案 1:取消摩擦(留存弹窗)

添加了一个 3 步留存弹窗:选择取消原因 → 提供替代方案(暂停、降级、折扣)→ 确认。效果:30 天 A/B 测试中,自愿取消率降低 18%。失败模式:弹窗里的替代方案不宜过多,每 session 上限 2 个,否则用户会产生反感。

修复方案 2:催款邮件序列(第 0/3/7/14 天)

一个由 Stripe invoice.payment_failed 触发的 4 封邮件催款序列。效果:14 天内挽回 41% 的失败付款(行业平均:22%–34%)。失败模式:不要用营销语气写催款邮件,需要用事务性语气,"更新付款方式"CTA 必须置于首屏。

修复方案 3:失败付款的智能重试

Stripe Smart Retries 默认开启,但大多数团队反而把它关掉了。重新启用并按本地时区调整重试时间。效果:相比基线催款序列,恢复率提升 9%。失败模式:重试次数不要超过 4 次;超过后恢复率跌至 4% 以下,还会惹恼发卡机构。

修复方案 4:年度套餐折扣门槛

在定价页上设置一键切换的 16% 年度套餐折扣。效果:年度转化率从 11% 升至 27%;锁定年度后流失率约为月度流失率的一半。失败模式:折扣不要超过 20%;否则会吸引专门薅折扣的用户,这批人在续约时流失率反而很高。

修复方案 5:基于使用量的降级(而非取消)

将取消流程替换为"降级"选项,允许用户保留账户但降为低档位并设置用量上限。效果:在到达降级页面的用户中,总取消率降低 23%。已标注: 若低档位的单元经济学低于支付处理成本,则此方案 ROI 为负;我在一个产品上测量到了这一点,随后对 9 美元以下档位撤销了降级选项。

修复方案 6:入职再激活(第 3/7 天)

在第 3 天(若用户未进入第二次会话)和第 7 天(若用户未进入第三次会话)触发再激活邮件,每封邮件均绑定用户尚未达成的具体激活事件。效果:在打开邮件的用户中,激活率提升 12%;未打开邮件的用户回落到基线。失败模式:此类邮件最多发 2 封;第 3 封邮件效果一致低于随机水平。

修复方案 7:赢回活动(60 天沉寂期)

对于 60 天未登录的用户,发送一封包含基于使用量折扣和一键"重新激活"CTA 的赢回邮件。效果:重新激活率 6%,每次重新激活平均挽回 11 美元净 MRR。失败模式:不要对少于 200 人的用户群运行此方案;数字不会稳定。

修复方案 8:定价页清晰度

将"Starter / Pro / Enterprise"替换为三个具体的使用量档位("每月 1,000 封邮件"、"每月 10,000 封邮件"、"每月 100,000 封邮件")。效果:30 天 A/B 测试中,"选错方案"导致的主动取消率降低 7%。失败模式:不要按功能数量命名档位;用户比较的是使用量,而非功能数量。

修复方案 9:客户健康评分(早期预警)

计算一个由 5 个信号组成的健康评分(最近登录时间、功能使用广度、支持工单量、最近一次 NPS 响应、支付历史),当付费账户评分跌破 30 时向客服告警。效果:在用户点击"取消"前,提前捕捉到 38% 的风险账户;其中 22% 通过主动联系成功挽留。失败模式:不要按原始分数变化触发告警;而是按周环比变化触发,以避免告警疲劳。

修复方案 10:主动支持外联

对于任何提交了标记为"bug"或"broken"支持工单的付费账户,创始人在 24 小时内主动外联,提供临时解决方案或修复时间表。效果:在有支持联系记录的用户群中,30 天流失率降低 14%。失败模式:不可规模化;当付费账户超过 200 个后需要专职客服人员,否则无法维持。

修复方案 11:年度检查(关系维护)

在每位付费账户的注册周年日向其发送一封创始人署名的年度检查邮件,汇总其全年使用数据。效果:年度续约率提升 3%。已标注: 对于月收入低于 30 美元的账户,此方案的 ROI 微薄;创始人时间成本超过可挽回的 ARR。仅对月收入 50 美元以上的账户保留此方案。

基准数据表(来自 9 家 SaaS 的真实中位数)

以下是 TanStack Ship 留存仪表板中渲染格式的矩阵。全部 9 个站点的数据均从 Stripe 计费事件中用同一查询拉取。

指标中位数(9 站)诚实区间团队常犯的错误
月度总流失率3.6%1.8%–7.8%将净流失率作为总流失率引用
自愿流失占比61%41%–78%未按流失原因分类
非自愿流失占比39%22%–59%无催款 = 收入损失
催款回收率(14 天)41%22%–58%使用营销语气写催款邮件
年度套餐占比27%8%–44%折扣超过 20%
降级替代取消率23%9%–37%低档位定价过低
健康评分挽留率22%11%–38%告警疲劳

我不会隐瞒的局限性

9 个站点是小样本。全部 9 个站点均为 TanStack Start 构建,因此数据偏向独立创始人栈而非销售主导型企业。催款回收率取决于支付处理器的地理分布和卡片类型;部分地区会偏高。中位数可复现——我用同一查询跑了两次——但这不是品类平均值。

实现方案:在 TanStack Start 中接入 Stripe 催款

以下 Stripe webhook 处理器和催款状态机随 TanStack Ship 一起发布。Webhook 运行在 Cloudflare Worker 上;状态机是 D1 表;邮件由 Cloudflare Queue 触发。

步骤 1:Stripe webhook 处理器

typescript
// app/routes/api/stripe-webhook.ts
import { stripe } from '~/lib/stripe'
import { sendDunningEmail } from '~/lib/dunning'

export async function action({ request }: { request: Request }) {
  const sig = request.headers.get('stripe-signature')!
  const body = await request.text()
  const event = await stripe.webhooks.constructEventAsync(body, sig, process.env.STRIPE_WEBHOOK_SECRET!)

  switch (event.type) {
    case 'invoice.payment_failed':
      const invoice = event.data.object as any
      await sendDunningEmail({
        customerId: invoice.customer,
        amount: invoice.amount_due,
        attempt: invoice.attempt_count,
        currency: invoice.currency,
      })
      break
    case 'invoice.paid':
      // 重置 D1 中的催款状态
      await fetch(`${process.env.APP_URL}/api/dunning/reset`, {
        method: 'POST',
        body: JSON.stringify({ customerId: event.data.object.customer }),
      })
      break
  }

  return new Response('ok')
}

步骤 2:催款状态机

typescript
// app/lib/dunning.ts
type DunningState =
  | { kind: 'ok' }
  | { kind: 'failed'; attempt: 1; nextEmailAt: Date }
  | { kind: 'failed'; attempt: 2; nextEmailAt: Date }
  | { kind: 'failed'; attempt: 3; nextEmailAt: Date }
  | { kind: 'failed'; attempt: 4; nextEmailAt: Date; paused: true }
  | { kind: 'recovered' }
  | { kind: 'canceled' }

export function nextState(current: DunningState, event: 'retry_failed' | 'payment_succeeded' | 'max_retries'): DunningState {
  if (event === 'payment_succeeded') return { kind: 'recovered' }
  if (current.kind !== 'failed') return current
  if (current.attempt >= 4 || event === 'max_retries') return { kind: 'canceled' }
  return { kind: 'failed', attempt: current.attempt + 1, nextEmailAt: addDays(new Date(), [3, 4, 7][current.attempt - 1]) }
}

状态机将重试次数上限设为 4 次;超过后账户进入暂停状态,用户必须更新支付方式才能进入下一个重试窗口。addDays 时间表为第 0、3、7、14 天——与上述基准数据测量时的窗口一致。

各修复方案的上线时机(优先级顺序)

若月度总流失率超过 5%,优先上线修复方案 2(催款)和修复方案 3(智能重试);两者无需改动产品即可挽回非自愿收入。随后上线修复方案 1(取消摩擦)和修复方案 5(降级替代取消)以解决自愿流失。健康评分监控(修复方案 9)属于第二季度问题;再激活(修复方案 6)也属于第二季度问题。年度检查(修复方案 11)属于第二年问题。

常见问题

SaaS 的"良好"月度流失率是多少?

对于 50 万美元 ARR 以下的独立创始人 B2B SaaS,9 个站点的诚实区间为月度总流失率 1.8%–7.8%,中位数为 3.6%。低于 2% 属于优秀且罕见。高于 5% 则意味着除非新客获取能力极强,否则流失在结构上已超过增长。

总流失率 vs 净流失率:应该报哪个?

两者都报。总流失率是诊断指标——反映产品留存能力。净流失率是报道指标——反映扩张是否在抵消流失。若只报一个,要么在掩盖留存问题,要么在掩盖扩张问题。

催款真的能挽回 41% 的失败付款吗?

在 9 站样本中是的。区间较大(22%–58%),因为取决于催款文案、重试时间安排,以及失败原因是真实拒付还是临时的发卡机构问题。Smart Retries 单独比基线催款序列多挽回约 9%。

TanStack Ship 在其中扮演什么角色?

Stripe webhook 处理器、催款状态机、4 封邮件序列和留存仪表板均随 TanStack Ship 启动包一起发布。上方的催款代码是运行在 TanStack Ship 构建的演示应用上的生产版本。如果你想预置 webhook、启用 Smart Retries、并获取已建好的 D1 schema,请查看功能页面和更新日志。


想将催款 webhook、状态机和 11 个修复方案预构建到你的 TanStack Start 项目中?TanStack Ship 全部包含,让你从 git clone 到带有流失回收率追踪的订阅流程,不到一天完成。查看功能列表、定价和更新日志。