리텐션 cohortMode 기본값 변경
리텐션 코호트 기본 정의가 first-ever로 바뀌며 기존 차트 수치가 달라질 수 있는 이유를 설명합니다.
리텐션 분석의 기본 cohort 정의가 first-ever로 바뀌었습니다.
기존 차트와 수치가 달라질 수 있으므로, 변경 이유와 복원 방법을 함께 확인하세요.
변경 요약
리텐션 분석의 cohort 정의가 두 가지로 분리되었고, 기본값이 first-ever(신규 유입 코호트)로 전환됩니다.
기존 동작은 first-in-window로 보존됩니다.
| 모드 | 정의 | 데이터 소스 |
|---|---|---|
first-ever (신규 기본) | 디바이스의 실제 최초 이벤트가 윈도우 내에 있을 때만 cohort에 포함. Mixpanel·Amplitude의 "신규 유입 cohort"와 동일. | device_first_seen MV (정밀 사전 집계) |
first-in-window (이전 기본) | 디바이스의 윈도우 내 첫 활동 시각을 cohort 앵커로 사용. 윈도우 밖에서 이미 활동한 디바이스도 포함. | events 테이블 직접 스캔 |
영향
이전에는 윈도우 밖에서 처음 등장한 디바이스라도 윈도우 내 활동이 있으면 그 시각을 cohort 앵커로 잡았습니다. first-ever로 바뀌면서 그 디바이스들은 cohort에서 제외됩니다. 신규 유입에 한정된 retention 곡선이라 더 정확하지만, 기존 차트와 cohort_size·rate 수치에 미세한 차이가 발생합니다.
윈도우 내 모든 디바이스가 그 윈도우에서 처음 등장한 데이터셋(예: 갓 출시한 프로젝트)에서는 두 모드 결과가 동일합니다.
이전 동작으로 보기
리텐션 페이지(/dashboard/<org>/<project>/retention) 상단의 코호트 정의 토글에서 First in window를 선택하면 변경 이전과 동일한 수치가 표시됩니다. tRPC 직접 호출 시에는 cohortMode: "first-in-window" 입력으로 동일.
성능
first-ever는 ClickHouse device_first_seen Materialized View(AggregatingMergeTree)를 읽어 events 테이블 풀 스캔을 피합니다. cohort 계산이 디바이스 수에 비례.
pnpm --filter @reopt/trpc bench:retention으로 측정한 로컬 ClickHouse(단일 코어, 콜드/웜 혼합) 결과:
| 데이터 크기 | events | first-in-window | first-ever (MV) | 절감 |
|---|---|---|---|---|
| 소 | 2,595 | 52ms | 25ms | -52% |
| 중 | 25,545 | 30ms | 21ms | -30% |
| 대 | 255,045 | 48ms | 38ms | -21% |
cohort 계산 단계에서 효과가 가장 두드러집니다(예: 대규모 21→11ms). 실 운영은 다중 동시 요청·다양한 segment·필터 조합·콜드 캐시가 섞여 절감량이 더 커지는 경향이 있습니다.
관련 라우터
analytics.analysisTools.retention.matrix—cohortMode입력 추가, 기본"first-ever"analytics.analysisTools.cohortComparison.compareRetention— 동일. 단 segment 필터가 cohort 멤버십에 필수이므로 first-ever 모드에서도 segment subquery는 유지 (segment 멤버 ∩ true first-seen ∈ window)
호환성
기존 클라이언트 코드가 cohortMode를 보내지 않으면 자동으로 "first-ever" 적용됩니다. 차트 수치 변화를 원하지 않는 경우 호출 측에서 cohortMode: "first-in-window"를 명시하세요.