跳到主要内容

留存分析

问题

什么是留存分析?如何计算留存率?留存分析有哪些常见方法?

答案

什么是留存分析

留存分析衡量用户在初始行为之后是否持续活跃。留存率越高,说明产品"黏住"了用户。

拉新花钱获取 100 个用户,如果次月只剩 20 个在用 → 次月留存率 20%

留存率类型

类型定义适用场景
N-day 留存第 N 天回来的用户占比次日留存、7 日留存
Unbounded 留存第 N 天及之后任一天回来长期留存趋势
Bracket 留存某时间段内回来的占比第 1-7 天、第 8-14 天
加权留存给不同天数赋权计算综合留存指标

N-day 留存 SQL 实现

计算次日留存、7日留存、30日留存
WITH first_visit AS (
-- 每个用户的首次访问日期
SELECT
user_id,
MIN(event_date) AS first_date
FROM user_events
GROUP BY user_id
),
retention AS (
SELECT
f.user_id,
f.first_date,
DATEDIFF(e.event_date, f.first_date) AS day_diff
FROM first_visit f
JOIN user_events e ON f.user_id = e.user_id
)
SELECT
first_date,
COUNT(DISTINCT user_id) AS cohort_size,
-- 次日留存
COUNT(DISTINCT CASE WHEN day_diff = 1 THEN user_id END) AS day1,
ROUND(COUNT(DISTINCT CASE WHEN day_diff = 1 THEN user_id END) * 100.0
/ COUNT(DISTINCT user_id), 1) AS day1_rate,
-- 7日留存
COUNT(DISTINCT CASE WHEN day_diff = 7 THEN user_id END) AS day7,
ROUND(COUNT(DISTINCT CASE WHEN day_diff = 7 THEN user_id END) * 100.0
/ COUNT(DISTINCT user_id), 1) AS day7_rate,
-- 30日留存
COUNT(DISTINCT CASE WHEN day_diff = 30 THEN user_id END) AS day30,
ROUND(COUNT(DISTINCT CASE WHEN day_diff = 30 THEN user_id END) * 100.0
/ COUNT(DISTINCT user_id), 1) AS day30_rate
FROM retention
GROUP BY first_date
ORDER BY first_date;

留存曲线

典型留存曲线呈"L 型"——前几天快速下降,然后趋于平稳:

留存率
100%|●
| ●
50%| ● ●
| ● ● ● ● ● ●
20%| ● ● ● ● ●
|__________________________________
D0 D1 D3 D7 D14 D30
留存曲线的三个关键位置
  1. 振荡期(Day 0~3):快速下降,与新用户体验强相关
  2. 选择期(Day 3~14):用户决定是否长期使用
  3. 稳定期(Day 14+):存活用户基本稳定,是产品"真实"留存

行业留存基准

行业次日留存7日留存30日留存
社交 App35~50%20~30%10~20%
电商20~30%10~15%5~10%
游戏30~45%15~25%5~15%
工具类40~60%25~40%15~25%
SaaS(B2B)-80~95%(周)70~90%
信息

以上为粗略参考,不同产品阶段和用户定义会有很大差异

提升留存的策略

阶段策略示例
新用户激活优化 Onboarding,让用户尽快到达 Aha MomentTwitter 引导关注 5 人
短期留存Push 触达、签到奖励外卖 App 连续登录红包
中期留存社交关系绑定、个性化推荐微信朋友圈
长期留存习惯养成、迁移成本笔记 App 数据积累

常见面试问题

Q1: 次日留存下降了,怎么排查?

答案

  1. 数据校验:埋点有没有问题?日活定义变了吗?
  2. 时间维度:从哪天开始下降?是否对应版本发布、运营活动结束?
  3. 用户维度:新用户 vs 老用户?哪个渠道的留存下降了?
  4. 行为维度:留存用户和流失用户的行为差异(用了哪些功能?)
  5. 外部因素:竞品促销、节假日效应、应用商店排名变化

Q2: 留存率和流失率是什么关系?

答案

  • 流失率 = 1 - 留存率(同一时间窗口下)
  • Day 7 留存率 25% → Day 7 流失率 75%
  • 但注意:留存率讲的是回来的,流失率讲的是没回来的

Q3: 什么是 Aha Moment?和留存有什么关系?

答案

  • Aha Moment:用户第一次感受到产品价值的时刻
  • 经典案例:Facebook 发现"7 天内加 10 个好友"的用户留存显著更高
  • 分析方法:对比留存用户和流失用户的早期行为,找到差异最大的特征
  • 找到 Aha Moment 后,产品引导用户尽快完成该行为

Q4: N-day 留存和 Unbounded 留存的区别?

答案

类型计算特点
N-day恰好第 N 天回来精确但波动大(周末效应)
Unbounded第 N 天或之后回来平滑但偏高
  • N-day 适合日常监控
  • Unbounded 适合向上汇报(数字更好看且更稳定)

Q5: 如何用 SQL 计算留存矩阵?

答案

留存矩阵(Cohort × Day)
WITH first_visit AS (
SELECT user_id, MIN(event_date) AS cohort_date
FROM user_events
GROUP BY user_id
)
SELECT
f.cohort_date,
COUNT(DISTINCT f.user_id) AS cohort_size,
-- 每个 day_diff 的留存率
ROUND(COUNT(DISTINCT CASE WHEN DATEDIFF(e.event_date, f.cohort_date) = 1
THEN e.user_id END) * 100.0 / COUNT(DISTINCT f.user_id), 1) AS d1,
ROUND(COUNT(DISTINCT CASE WHEN DATEDIFF(e.event_date, f.cohort_date) = 3
THEN e.user_id END) * 100.0 / COUNT(DISTINCT f.user_id), 1) AS d3,
ROUND(COUNT(DISTINCT CASE WHEN DATEDIFF(e.event_date, f.cohort_date) = 7
THEN e.user_id END) * 100.0 / COUNT(DISTINCT f.user_id), 1) AS d7,
ROUND(COUNT(DISTINCT CASE WHEN DATEDIFF(e.event_date, f.cohort_date) = 14
THEN e.user_id END) * 100.0 / COUNT(DISTINCT f.user_id), 1) AS d14,
ROUND(COUNT(DISTINCT CASE WHEN DATEDIFF(e.event_date, f.cohort_date) = 30
THEN e.user_id END) * 100.0 / COUNT(DISTINCT f.user_id), 1) AS d30
FROM first_visit f
LEFT JOIN user_events e ON f.user_id = e.user_id
GROUP BY f.cohort_date
ORDER BY f.cohort_date;

相关链接