1 정의
새 Treatment 를 즉시 100% 사용자에 노출하지 않고, 점진적으로 traffic 비중을 늘리는 절차 (Kohavi, Tang, Xu, 2020, Ch.15).
1.0.0.1 4 단계 흐름
Step 1: 0% → 1~5% (소수 ring 노출 + 신뢰성 확인)
Step 2: 5~10% → MPR 50% (precise 측정)
Step 3: 50% → 75% → 90% (operational scaling)
Step 4: 90% → 100% (또는 long-term holdout 90%/10%)
1.0.0.2 Why 단계적
- Risk mitigation: bug 발견 시 영향 사용자 수 ↓
- Quality measurement: MPR 에서 가장 정확한 effect estimate
- Operational scaling: 새 service 의 traffic 부담 단계적 검증
- Long-term learning: novelty·primacy effect 분리
원문 (Thomas A. Edison): “The real measure of success is the number of experiments that can be crowded into 24 hours.”
핵심 통찰: ramping 의 목적은 단순 risk 회피 가 아니라 speed·quality·risk 의 동시 최적화. 너무 천천히 ramp = speed loss, 너무 빨리 ramp = quality 또는 risk damage. SQR framework 가 이 trade-off 의 명시 도구.
2 개념 및 원리
2.1 Why Care — Healthcare.gov 사례의 교훈
저자가 도입에서 인용 (Levy 2014).
2.1.0.1 Healthcare.gov launch 의 사고 (2013)
배경:
미국 Affordable Care Act 의 핵심 web platform
수백만 사용자가 health insurance 가입 예정
Launch 결정:
Day 1 에 100% 사용자 노출 (no ramping)
결과:
- 시스템 collapse (load 처리 불가)
- 사용자 며칠 ~ 몇 주 가입 불가
- 정치적 위기, 행정부 신뢰 손상
- 비용 수억 달러 추가
2.1.0.2 만약 ramping 했다면
대안: 지역별 또는 last-name A-Z 단계 rollout
Day 1: 일부 주 (5%) 만 노출
Day 2: 추가 주 (15%)
...
장점:
- Load 점진 증가 → bottleneck 점진 발견·해결
- 사고 시 영향 사용자 5%
- 시스템 학습 + 적응 시간
이 ramping 부재가 사고의 직접 원인.
2.1.0.3 산업 표준의 lesson
저자 강조: “Insisting on a ramping process became a key lesson for subsequent launches.”
이후 미국 정부 platform launches:
- Healthcare.gov 의 redesign (2014~)
- 다른 federal services
- 모두 ramping process 필수
산업 일반:
- "Big bang launch" 거부
- Ramped rollout 표준
- Feature flag system 의 prerequisite
이 사례가 ramping 의 가치를 사회적으로 증명. Big launch 의 일회성 risk vs gradual ramp 의 운영 적 안전 사이 후자의 명백한 우위.
2.2 SQR Framework — 3 차원 trade-off
저자 명시 (Ch.15.1).
2.2.1 3 차원의 정의
2.2.1.1 Speed — 실험의 진행 속도
Speed 의 정의:
- 새 feature idea → 100% launch 까지 시간
- 더 빠를수록 ↑
Speed 의 가치:
- 시장 경쟁력 (faster iteration)
- Innovation throughput
- 사용자에 빠른 가치 제공
2.2.1.2 Quality — 측정의 정확성
Quality 의 정의:
- Effect estimate 의 정확도
- Variance 의 정확도
- 결정의 trustworthiness
Quality 의 가치:
- Launch 결정의 정확성
- 잘못된 launch 의 사고 회피
- Long-term ROI
2.2.1.3 Risk — 사용자·비즈니스 손해
Risk 의 정의:
- 잘못된 Treatment 의 사용자 노출
- 비즈니스 metric 손실
- System failure 의 가능성
Risk 의 가치:
- 사용자 경험 보호
- 비즈니스 안정성
- 신뢰 자산
2.2.2 3 차원의 trade-off
Triangle:
Speed ─── Quality
\ /
\ /
\ /
Risk
각 corner 만 추구 시:
Speed only → 즉시 100% (Healthcare.gov 사고)
Quality only → 영원히 50% MPR (launch 안 함)
Risk only → 0% 유지 (변화 거부)
Balance:
- 모든 corner 의 일정 비중
- Phase 별 다른 priority
- SQR framework 가 명시 도구
각 ramp phase 가 SQR 중 다른 차원 우선.
2.2.2.1 Phase 1 (Pre-MPR): Risk vs Speed
이 단계의 목표: Risk 최소화 + 빠른 진행
Quality 는 후순위 (sample size 적어 quality 어려움)
전략:
- 작은 ring (whitelist, employee) 부터
- 빠른 dial-up (자동)
- Real-time guardrail
2.2.2.2 Phase 2 (MPR): Quality vs Speed
이 단계의 목표: Quality 측정 + 빠른 진행
Risk 는 phase 1 에서 이미 처리
전략:
- 50% 비중 (statistical power 최대)
- 1 주 이상 (time-dependent factors)
- 정확한 effect estimate
2.2.2.3 Phase 3 (Post-MPR): Operational
이 단계의 목표: Operational scaling
Speed·Quality·Risk 모두 정상 (이미 검증)
전략:
- 75%, 90% 단계
- Engineering infrastructure 검증
- Peak traffic 모니터링
2.2.2.4 Phase 4 (Holdout): Long-term Learning
이 단계의 목표: Long-term learning + Replication
SQR 외 추가 차원 (long-term truth)
전략:
- 90%/10% holdout
- 수개월 유지
- Novelty·primacy effect 분리
2.2.2.5 본질 — Phase 별 다른 SQR 우선
Phase 1: R > S > Q
Phase 2: Q > S > R
Phase 3: S > Q > R (R 거의 0)
Phase 4: Quality (long-term) 단독
이 phase-by-phase mindset 이 SQR framework 의 본질. 모든 phase 에 같은 priority 가 아닌, 각 phase 가 다른 trade-off 결정 을 명시.
2.2.3 MPR (Maximum Power Ramp) 의 통계적 유래
저자 footnote (Ch.15.1, footnote 1).
2.2.3.1 50/50 split 이 최대 power 인 이유
Two-sample t-test 의 variance:
Variance ∝ 1/q + 1/(1-q)
where q = treatment 비율
이 함수가 minimize 될 때 power 최대.
미분:
d/dq [1/q + 1/(1-q)] = -1/q² + 1/(1-q)² = 0
→ 1/q² = 1/(1-q)²
→ q = 1-q
→ q = 0.5
따라서 50/50 split 이 statistical power 최대.
2.2.3.2 일반화 — 100% 미만 traffic 시
20% traffic 만 실험에 사용 가능 시:
Treatment + Control = 20%
MPR: 10% Treatment + 10% Control
나머지 80% 는 다른 Treatment 또는 baseline
4 variants split 100% traffic:
각 variant: 25%
MPR: 25% × 4 (균등)
2.2.3.3 MPR 의 본질
MPR 의 의미:
"Statistical power 이 최대인 traffic split"
표준: 50/50 (Treatment vs Control 단독 시)
Why MPR 에서 quality 측정?
- Variance 최소
- Effect 의 정확한 추정
- Confidence interval 가장 좁음
- Decision 의 most reliable 시점
이 통계적 본질이 phase 2 의 50% 결정의 근거.
2.3 4 Ramp Phases 의 지도
저자가 명시한 4 단계 (Xu et al. 2018).
2.3.1 Phase 1 — Pre-MPR (Risk Mitigation)
2.3.1.1 목표
- Risk 최소화 (모르는 bug 노출 ↓)
- 빠르게 MPR 도달
2.3.1.2 3 가지 기법
저자 명시.
1. Rings of testing populations (점진적 ring 노출):
a) Whitelist (개발 팀 자체)
- 즉시 노출 가능
- Verbatim feedback
- Sample size 거의 0
b) Company employees
- 더 많은 sample
- "직원이 더 forgiving"
- 일부 measure 가능
c) Beta users / Insiders
- Vocal, loyal user
- Quantitative + qualitative feedback
- Selection bias 인정 ("insider")
d) Data center isolation
- 단일 data center 의 사용자 (~0.5~2%)
- Memory leak, resource issue 등 catch
- Bing 의 표준 (저자 명시)
2. Auto dial-up:
- 자동으로 traffic % 증가
- Pre-set schedule (예: 5% → 10% → 25%)
- 1 시간 단위 증가 (extra hour)
- Bug 영향 minimal
3. Real-time guardrail:
- 핵심 metric 의 실시간 모니터링
- Anomaly 시 즉시 alert
- 빠른 결정 가능
2.3.2 Phase 2 — MPR (Quality Measurement)
2.3.2.1 목표
- 정확한 effect estimate
- Trustworthy 결정 근거
2.3.2.2 핵심 권고
저자 명시: “We want to highlight our recommendation to keep experiments at MPR for a week, and longer if novelty or primacy effects are present.”
Why 1 주?
- Time-dependent factors:
- Weekday vs weekend 차이
- Heavy user (daily) vs light user (weekly)
- 1 일 분석 시 heavy user bias
- 1 주 후 diminishing return:
- Variance 감소가 둔화
- 추가 시간의 ROI ↓
- 단 novelty·primacy effect 시 확장 필요
If novelty/primacy effect:
- 첫 며칠 의 효과가 사용자 학습 후 변화
- 더 긴 측정 필요 (2~4 주)
2.3.2.3 Time-dependent factor 의 메커니즘
1-day 실험 의 sample bias:
- Heavy user (매일 visit) 가 비율 ↑
- Light user (주 1 회) 가 underrepresented
- Effect estimate: heavy user 중심 → biased
7-day 실험:
- Light user 도 1 회 이상 visit
- Sample 이 user base 대표
- Effect estimate 정확
2.3.3 Phase 3 — Post-MPR (Operational Scaling)
2.3.3.1 목표
- Engineering infrastructure 의 traffic 부담 검증
- 100% 도달
2.3.3.2 특성
저자 명시: “By the time an experiment is past the MPR phase, there should be no concerns regarding end-user impact. Optimally, operational concerns should also be resolved in earlier ramps.”
75%, 90% 단계의 의미:
- 사용자 영향: 이미 검증 (phase 1, 2)
- 인프라 영향: 새 service 의 load 검증
- Peak traffic 시 monitor (rush hour 등)
각 단계 SLA: 1 일 이하
- 빠르게 진행
- Anomaly 없으면 다음 단계
- 인프라 issue 발견 시 hold + fix
2.3.4 Phase 4 — Long-Term Holdout / Replication
2.3.4.1 목표
- Long-term effect 측정
- Novelty·primacy effect 분리
- Replication 으로 결과 확인
2.3.4.2 Holdout 의 정의
Holdout (Holdback):
- 일부 사용자 (5~10%) 가 Treatment 안 받음
- 장기간 (수개월) 유지
- Long-term effect 측정 reference
2.3.4.3 Holdout 사용의 3 가지 시나리오
저자 명시.
시나리오 1: Long-term effect ≠ short-term effect
a) Novelty/primacy effect 있는 영역
b) 단기 impact 가 너무 커서 sustainability 검증 필요
c) 단기 impact 작은데 long-term 효과 있다는 가설
시나리오 2: Early indicator
- 단기 metric 효과 있음
- True-north metric (1 개월 retention) 은 long-term
시나리오 3: Variance 감소
- 더 긴 시간 = variance ↓
- Sensitivity ↑ (Ch.22)
2.3.4.4 Replication 의 가치
저자 강조: “When experiment results are surprising, a good rule of thumb is to replicate them.”
Replication 의 메커니즘:
- 같은 실험을 다른 사용자 set 으로 재실행
- 또는 orthogonal re-randomization
- 결과 일치 시 trustworthy
- 결과 다르면 spurious
Multi-iteration 실험의 함정:
- 같은 실험을 여러 번 iterate
- 가장 좋은 결과를 final 로 채택 시 selection bias
- Replication 으로 unbiased estimate 회복
이것이 Ch.17 (Computing Experiment Effects) 와 cross-link.
2.4 Post Final Ramp — Cleanup의 중요성
저자 명시 (Ch.15.4).
2.4.1 Cleanup 의 필요성
실험이 100% launched 후:
- Treatment 코드가 production 의 default
- Control (이전 default) 의 dead code path
- Feature flag 의 lock-in
2.4.1.1 두 가지 architecture 별 cleanup
저자 분석.
1. Code fork architecture:
if variant == treatment:
new_logic()
else:
old_logic() # dead code path after 100% launch
Cleanup:
- new_logic() 만 유지
- old_logic() 제거
- if 분기 자체 제거
2. Parameter system architecture:
value = config.get("param", default=old_value)
Cleanup:
- default = new_value 로 교체
- if 가 없음 → cleanup 더 단순
2.4.1.2 Cleanup 안 하면
저자 강조: “in the first case, it can be disastrous when a dead code path that is not being maintained for a while is accidentally executed, which could happen when the experiment system has an outage.”
Dead code path 의 risk:
- 1 년 maintain 안 됨 → 다른 code change 가 incompatible 가능
- Experiment system outage 시 default fallback 으로 dead path 실행
- 사용자 broken experience
- 발견까지 시간 lag (rare path)
2.4.1.3 Cleanup 의 SLA
산업 표준:
Launch 후 1~2 개월 내 cleanup
Cleanup 자체도 자체 PR + review
Code review 에서 cleanup 강제
이 cleanup 절차가 production health 의 sustainability. Fast-moving dev process 에서 자주 빠짐.
가정: 모든 launched 실험의 dead code path 를 그대로 둠.
2.4.1.4 1 년 후 시나리오
1 년 동안 100 개 실험 launched.
→ 100 개의 dead code path 누적
→ Production codebase 의 50% 가 dead code
영향:
- Code review 시 reviewer 의 cognitive load ↑
- 새 feature 개발 시 어디 수정해야 모름
- Refactoring 어려움 (dead code 영향 미상)
- Build time, deploy time ↑
- Bug 발견 어려움 (dead code 의 bug)
2.4.1.5 사고 시나리오
2 년 후의 outage:
- Experiment system down
- Default 가 일부 fallback 으로 dead code path 사용
- 1 년 전 launched 실험의 old logic 실행
- 그동안 다른 code 변경으로 incompatibility
- 사용자 broken experience
- Engineer: "이 코드 누가 썼지? 왜 있지?" confusion
2.4.1.6 해결
1. 명시 cleanup process:
- Launch 시 cleanup ticket 자동 생성
- 1~2 개월 내 cleanup deadline
2. Linter:
- Dead code path 자동 detect
- "이 if 의 else 는 절대 reach 안 됨" warning
- Refactor 권고
3. Code archaeology:
- 분기 별 production audit
- Old experiment flag 식별
- Cleanup PR 일괄
이 cleanup 운영이 mature platform 의 silent quality. 실험 platform 의 한 가지 차원.
3 왜 필요한가
Ramping 부재 시.
- Big bang launch 사고 — Healthcare.gov 평행 (시스템 collapse, 사용자 영향)
- Bug 영향 maximize — 모든 사용자가 동시 broken feature 노출
- Operational risk — Traffic 부담의 갑작스러운 증가 → infrastructure 부족
- Quality 부족 — Effect 측정 시간 부족 → 잘못된 launch 결정
Ramping 활성 시.
- Risk 단계적 mitigation — 작은 ring 부터 점진 노출
- Quality 시간 — MPR 의 1 주 이상 → 정확한 측정
- Operational 검증 — 인프라 부담의 단계적 검증
- Long-term truth — Holdout 으로 sustainability 측정
이 격차가 production stability 의 본질. Ramping process 가 platform 의 운영 골격.
4 응용 사례 — 회사별 Ramping schedule
| 회사 | Pre-MPR | MPR | Post-MPR | Holdout |
|---|---|---|---|---|
| Microsoft Office | 1% (1d) → 5% (1d) → 25% (1d) | 50% (1주) | 75% (1d) → 100% | 10% holdout (월) |
| Bing | 0.5% (1 dc, 1d) → 1% (1d) → 5% (1d) | 50% (1주) | 90% (1d) → 100% | Global 10% 영구 |
| 1% (1d) → 5% (1d) → 25% (1d) | 50% (1주) | 100% (1d) | Selective | |
| 1% (1d) → 5% (1d) → 25% (1d) | 50% (1주) | 75% (1d) → 100% | Selective |
각 회사의 ramping schedule 이 미세하게 다르지만 4 phase 구조 동일. SQR framework 가 산업 표준.
5 Ch.15 시리즈 다음 글
| 글 | 주제 | KOH 라인 |
|---|---|---|
| F15-1 | What Is Ramping + SQR Framework | L:2666~2691 |
| F15-2 | Four Ramp Phases — Pre-MPR / MPR / Post-MPR | L:2692~2727 |
| F15-3 | Long-Term Holdout/Replication + Post Final Ramp | L:2728~2750 |
6 코드 예시 — Ramp schedule 시뮬레이션
자동 dial-up + guardrail 모니터링 시뮬레이션.
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
rng = np.random.default_rng(42)
# Ramp schedule
ramp_schedule = [
{"phase": "Pre-MPR Ring 1", "treatment_pct": 1, "duration_hours": 4, "guardrail_threshold": 0.10},
{"phase": "Pre-MPR Ring 2", "treatment_pct": 5, "duration_hours": 8, "guardrail_threshold": 0.10},
{"phase": "Pre-MPR Ring 3", "treatment_pct": 25, "duration_hours": 12, "guardrail_threshold": 0.10},
{"phase": "MPR", "treatment_pct": 50, "duration_hours": 24*7, "guardrail_threshold": 0.05},
{"phase": "Post-MPR", "treatment_pct": 75, "duration_hours": 24, "guardrail_threshold": 0.05},
{"phase": "Final", "treatment_pct": 100, "duration_hours": 0, "guardrail_threshold": None},
]
# Treatment 의 진정 효과
true_effect = -0.03 # -3% on guardrail (예: latency increase)
# 각 phase 의 결과 시뮬레이션
results = []
for phase in ramp_schedule:
n_users = int(100_000 * phase["treatment_pct"] / 100 * (phase["duration_hours"] / 24))
if n_users == 0:
continue
# Treatment guardrail metric
baseline_metric = rng.normal(100, 20, n_users)
treatment_metric = baseline_metric * (1 + true_effect + rng.normal(0, 0.001))
# Control guardrail metric (같은 시간)
control_metric = rng.normal(100, 20, n_users)
# 측정된 effect
measured_effect = (treatment_metric.mean() - control_metric.mean()) / control_metric.mean()
# Guardrail check
guardrail_threshold = phase["guardrail_threshold"]
alert = guardrail_threshold is not None and abs(measured_effect) > guardrail_threshold
results.append({
"phase": phase["phase"],
"treatment_pct": phase["treatment_pct"],
"duration_h": phase["duration_hours"],
"n_users": n_users,
"measured_effect": measured_effect,
"threshold": guardrail_threshold,
"alert": alert,
})
df = pd.DataFrame(results)
print(df.to_string(index=False))
# Phase 별 사용자 영향 누적
df["cumulative_users_affected"] = df["n_users"].cumsum()
print(f"\n=== 누적 영향 사용자 ===")
print(df[["phase", "treatment_pct", "n_users", "cumulative_users_affected"]].to_string(index=False))
# 만약 guardrail alert
print(f"\n=== Alert 분석 ===")
alerts = df[df["alert"]]
if len(alerts) > 0:
first_alert = alerts.iloc[0]
affected_until_alert = df[df["phase"] == first_alert["phase"]].iloc[0]["cumulative_users_affected"]
print(f"First alert in phase: {first_alert['phase']}")
print(f"Treatment %: {first_alert['treatment_pct']}%")
print(f"Affected users until alert: {affected_until_alert:,}")
print(f"\n*** ACTION: Hold ramp, investigate root cause ***")
else:
print("No alerts. Continue ramp.")
# 만약 ramping 없이 100% 즉시 launch 했다면
print(f"\n=== 만약 ramping 없이 즉시 100% ===")
n_total_users = 100_000 # 가상의 일별 사용자
days_to_detect = 1 # alert 까지 1 일 걸림
affected_users_no_ramp = n_total_users * days_to_detect
print(f"Affected users (no ramping): {affected_users_no_ramp:,}")
print(f"Ramping vs no-ramping affected users ratio: "
f"{affected_users_no_ramp / df['n_users'].iloc[0]:.0f}x")예상 출력 (시드 42 — random 변동).
phase treatment_pct duration_h n_users measured_effect threshold alert
Pre-MPR Ring 1 1 4 166 -0.022672 0.10 False
Pre-MPR Ring 2 5 8 1666 -0.030291 0.10 False
Pre-MPR Ring 3 25 12 12500 -0.029999 0.10 False
MPR 50 168 350000 -0.029967 0.05 False
Post-MPR 75 24 75000 -0.030092 0.05 False
=== 누적 영향 사용자 ===
phase treatment_pct n_users cumulative_users_affected
Pre-MPR Ring 1 1 166 166
Pre-MPR Ring 2 5 1666 1832
Pre-MPR Ring 3 25 12500 14332
MPR 50 350000 364332
Post-MPR 75 75000 439332
=== Alert 분석 ===
No alerts. Continue ramp.
=== 만약 ramping 없이 즉시 100% ===
Affected users (no ramping): 100,000
Ramping vs no-ramping affected users ratio: 602x
이 시뮬레이션의 4 가지 메시지.
1. Pre-MPR 단계의 사용자 보호
Phase 1 (Ring 1, 1%): 166 사용자만 영향. 만약 bug 발견 시 영향이 1/600 으로 감소.
이것이 ramping 의 핵심 가치. 사고 시 영향 사용자 수의 dramatic 감소.
2. Threshold 의 phase 별 다름
Pre-MPR: 10% (loose)
MPR: 5% (strict)
Pre-MPR 에서는 작은 sample 이라 noise 크니 loose threshold. MPR 에서 sample 크니 strict.
3. Effect 의 정확도 phase 별
Phase 1 (1% pop): measured -2.27% (noise 큼)
Phase 4 (50%): measured -3.00% (true 와 일치)
MPR 에서야 정확. 따라서 launch 결정은 MPR 결과 기반.
4. Cumulative impact 의 dramatic 차이
Ramping (5 phases):
- Phase 1 alert 시 affected: 166 명
- Phase 4 alert 시 affected: 364,332 명 (대부분이 50% MPR 도달)
No ramping:
- 즉시 100% 의 1 일: 100,000+ 명 영향
이 차이가 ramping 의 risk mitigation 가치.
6.0.0.1 Healthcare.gov 의 평행 시뮬레이션
실제 사고:
Day 1: 100% rollout
Day 1 collapse: 시스템 down, 모든 사용자 영향
Recovery: 며칠 ~ 몇 주
만약 ramping:
Day 1 (1%): 일부 주만 → load 부족, but functional
Day 1 collapse 발견 시:
- 영향: 1% 사용자 (수만 명)
- 1% 으로는 단일 region 만
- Recovery: 즉시 hold
Day 2~: load 검증 후 ramp
이 평행이 정부·대형 platform 의 표준 ramping.
7 관련 주제
선행
- F4-3 — 인프라·도구 — Feature flag system
- F12-2 — Implication 1 (Anticipate) — Pre-shipped variant
다음 글
- F15-1 — What Is Ramping + SQR Framework
- F15-2 — Four Ramp Phases
- F15-3 — Long-Term Holdout/Replication + Post Final Ramp
관련 챕터
- F8-* — Ch.8 제도적 기억 (Best Practices) — Ramp 통계의 메타분석
- F19-* — Ch.19 A/A Test — Ramp 시작 전 검증
- F23-* — Ch.23 장기 효과 — Long-term holdout
다른 카테고리 연결
- Engineering — Feature Flag · Canary Deploy — LaunchDarkly, Unleash
- Engineering — Blue-Green Deploy — 인프라 ramp
- Statistics — Statistical Power — MPR 의 통계적 본질
- Surveilance — Phase I/II/III 임상시험 — 의료 평행