docs(10_Wiki): Topic_Business/General/Graphic/Programming을 Topics/ 하위로 이동
최상위 10_Wiki/Topic_*였던 4개 카테고리 폴더를 10_Wiki/Topics/Topic_* 로 재배치. 콘텐츠 변경 없음(순수 폴더 이동) — Topics/ 하위 나머지 폴더는 이미 지난 커밋에서 전부 정리된 상태(잔존 항목은 에이전트 운영 상태 및 사용자가 보존을 요청한 업데이트0615/무제 3.canvas 뿐).
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
---
|
||||
id: wiki-2026-0508-리텐션-retention
|
||||
title: 리텐션 (Retention)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Retention, User Retention, Player Retention, D1/D7/D30]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [game-design, product, kpi, growth, monetization]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: SQL/Python
|
||||
framework: BigQuery / dbt
|
||||
---
|
||||
|
||||
# 리텐션 (Retention)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 리텐션은 game/product의 진정한 PMF(product-market fit) 신호다"**. 매 acquisition은 marketing이 만들지만 retention은 product 자체의 함수이며 매 D1/D7/D30 retention curve 의 shape 가 LTV·CAC·viability 를 결정한다.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Retention 정의
|
||||
- **Classic (N-day)**: 매 cohort 의 day-N 재방문 비율. D1, D7, D30 이 standard.
|
||||
- **Rolling N-day**: 매 day-N±k window 내 재방문 — mobile 에 적합.
|
||||
- **Bracket**: 매 누적 active in [N1, N2] window — mature product 에 적합.
|
||||
|
||||
### 매 모바일 게임 benchmark (2026)
|
||||
- **Hyper-casual**: D1 35-40%, D7 10-15%, D30 3-5%.
|
||||
- **Mid-core**: D1 45-55%, D7 20-25%, D30 8-12%.
|
||||
- **Hardcore RPG**: D1 50-60%, D7 30-40%, D30 15-20%.
|
||||
- **Top decile**: 매 D1 ≥ 55%, D7 ≥ 30%, D30 ≥ 15%.
|
||||
|
||||
### 매 Retention drivers
|
||||
- **Onboarding**: 매 first-session 5-min 의 magic moment 도달 비율.
|
||||
- **Daily habit**: 매 daily login reward, daily quest, energy regen.
|
||||
- **Social**: 매 guild, friend list, leaderboard.
|
||||
- **Progression**: 매 visible mastery curve (level, gear, collection).
|
||||
- **Live ops**: 매 limited-time events, seasonal pass, FOMO.
|
||||
|
||||
### 매 응용
|
||||
1. 매 D1 < 30% → onboarding/first-session 문제. 매 fix 우선순위 1.
|
||||
2. 매 D1 OK but D7 cliff → core loop 단조 → progression/variety 부족.
|
||||
3. 매 D30 OK but stagnant → endgame/social content 부족.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Cohort retention SQL
|
||||
```sql
|
||||
WITH cohort AS (
|
||||
SELECT user_id, DATE(MIN(event_time)) AS install_date
|
||||
FROM events WHERE event = 'install'
|
||||
GROUP BY user_id
|
||||
),
|
||||
activity AS (
|
||||
SELECT e.user_id, c.install_date,
|
||||
DATE_DIFF(DATE(e.event_time), c.install_date, DAY) AS day_n
|
||||
FROM events e
|
||||
JOIN cohort c USING (user_id)
|
||||
WHERE e.event = 'session_start'
|
||||
)
|
||||
SELECT install_date, day_n,
|
||||
COUNT(DISTINCT user_id) AS retained,
|
||||
COUNT(DISTINCT user_id) * 1.0
|
||||
/ FIRST_VALUE(COUNT(DISTINCT user_id))
|
||||
OVER (PARTITION BY install_date ORDER BY day_n) AS retention_rate
|
||||
FROM activity
|
||||
WHERE day_n IN (0,1,3,7,14,30)
|
||||
GROUP BY install_date, day_n;
|
||||
```
|
||||
|
||||
### Retention curve fit (power law)
|
||||
```python
|
||||
import numpy as np
|
||||
from scipy.optimize import curve_fit
|
||||
|
||||
def power_law(d, a, b):
|
||||
return a * (d + 1) ** -b
|
||||
|
||||
days = np.array([1,3,7,14,30,60])
|
||||
ret = np.array([0.45, 0.30, 0.22, 0.16, 0.10, 0.07])
|
||||
(a, b), _ = curve_fit(power_law, days, ret)
|
||||
# extrapolate D90, D365
|
||||
print(power_law(90, a, b), power_law(365, a, b))
|
||||
```
|
||||
|
||||
### LTV from retention + ARPDAU
|
||||
```python
|
||||
def ltv(retention_curve, arpdau, horizon_days=365):
|
||||
return sum(retention_curve(d) * arpdau for d in range(1, horizon_days+1))
|
||||
```
|
||||
|
||||
### Daily login streak service
|
||||
```typescript
|
||||
async function claimDailyReward(userId: string) {
|
||||
const u = await users.get(userId);
|
||||
const today = todayUTC();
|
||||
if (u.lastLoginDate === today) throw new Error('already-claimed');
|
||||
const isContinuation = u.lastLoginDate === yesterdayUTC();
|
||||
const newStreak = isContinuation ? u.streak + 1 : 1;
|
||||
const reward = REWARD_TABLE[Math.min(newStreak - 1, REWARD_TABLE.length - 1)];
|
||||
await users.update(userId, { streak: newStreak, lastLoginDate: today });
|
||||
await inventory.grant(userId, reward);
|
||||
return { streak: newStreak, reward };
|
||||
}
|
||||
```
|
||||
|
||||
### Churn risk model (lightweight)
|
||||
```python
|
||||
# features: days_since_install, sessions_last_7d, spend_total, level, social_count
|
||||
# label: churned (no session in next 14 days)
|
||||
from sklearn.ensemble import GradientBoostingClassifier
|
||||
clf = GradientBoostingClassifier(max_depth=3, n_estimators=200)
|
||||
clf.fit(X_train, y_train)
|
||||
# segment top-K churn-risk users → targeted re-engagement push
|
||||
```
|
||||
|
||||
### Re-engagement campaign trigger
|
||||
```typescript
|
||||
// trigger if user inactive 3-7 days, segment by spend, send personalized offer
|
||||
async function triggerReengagement() {
|
||||
const candidates = await db.query(`
|
||||
SELECT user_id, last_session, total_spend, favorite_mode
|
||||
FROM users
|
||||
WHERE last_session BETWEEN NOW() - INTERVAL 7 DAY AND NOW() - INTERVAL 3 DAY
|
||||
`);
|
||||
for (const c of candidates) {
|
||||
const offer = c.total_spend > 50 ? 'whale_comeback' : 'soft_nudge';
|
||||
await push.send(c.user_id, OFFER_TEMPLATES[offer](c));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| D1 낮음 | Onboarding/FTUE 재설계, magic moment time-to-fun ↓ |
|
||||
| D7 cliff | Daily habit loop (login reward, quest), variety injection |
|
||||
| D30 정체 | Endgame, guild/social, seasonal pass |
|
||||
| Whale retention | Personalized live-ops, VIP CS, exclusive events |
|
||||
| New genre | Power-law extrapolation 의 X — empirical curve 만 trust |
|
||||
|
||||
**기본값**: 매 D1/D7/D30 cohort tracking + power-law LTV proxy + churn-risk segmentation.
|
||||
|
||||
## 🔗 Graph
|
||||
- 응용: [[디아블로_2(Diablo_II)]] · [[클래시_로얄(Clash_Royale)]] · [[알비온_온라인(Albion_Online)]] · [[가차(Gacha)]]
|
||||
- Adjacent: [[부분_유료화(Free-to-Play)]] · [[하이브리드_수익화(Hybrid_Monetization)]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 retention curve 진단, segment 별 churn 원인 hypothesis, live-ops content idea, A/B test design.
|
||||
**언제 X**: 매 specific causation 결론 (correlation only without experiment), 매 individual user prediction (privacy/legal).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Vanity DAU**: 매 retention 무시한 acquisition push → CAC payback 실패.
|
||||
- **D1 만 보기**: 매 D7/D30 무시 → long-term LTV 왜곡.
|
||||
- **Linear extrapolation**: 매 retention 은 power-law — 매 linear projection 은 LTV 과대평가.
|
||||
- **Forced daily login**: 매 punishment-based streak → resentment + uninstall.
|
||||
- **Pay-to-retain**: 매 monetization 위 retention 의존 → churn rate 가속.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (GameAnalytics 2025 benchmarks, Sensor Tower 2025 mobile gaming report, "Lean Analytics" Croll/Yoskovitz).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — D1/D7/D30 cohort + LTV + churn patterns |
|
||||
Reference in New Issue
Block a user