1 정의
Kohavi (2020) Ch.13.1 가 명시한 두 시각은 다른 질문에 답하는 도구 이다.
| 시각 | 답하는 질문 | 보지 못하는 것 |
|---|---|---|
| Client-Side | “사용자가 무엇을 보고, 어떻게 했나?” | 시스템 내부 상태, 분기 |
| Server-Side | “시스템이 무엇을 했고, 왜 그렇게 했나?” | 사용자가 actual 본 것, client-only 행동 |
저자 강조 (Edmons et al. 2007, Zhang, Joseph and Rickabaugh 2018): “When implementing instrumentation, understanding what happens client side vs. server side is important.”
핵심 통찰: 둘 중 하나만 으로는 사용자 의 행동도, 시스템의 내부도 완전히 알 수 없다. 양면이 결합되어야 user-system 상호작용의 full picture. 그러나 둘 모두 challenge 와 cost 가 있어 실무 에서는 trade-off 결정이 필요하다.
2 개념 및 원리
2.1 Client-Side Instrumentation 의 시각
2.1.1 3 가지 client 계측 영역
저자가 명시한 분류 (Ch.13.1).
2.1.1.1 영역 1 — User Actions
사용자가 client 에서 수행하는 모든 행동.
Click events:
- 어떤 element click (button, link, image)
- Click 의 정확한 시점 (millisecond)
- 사용자 device, browser, OS
Hover events:
- Mouse 가 element 위에 머문 시간
- 어떤 element 에 관심 보였는가
- Click 으로 이어졌는가
Scroll events:
- 사용자가 page 의 어느 깊이까지 봤는가
- Scroll velocity (빠른지 느린지)
- Long-form content 의 read-through rate
Form interactions:
- 어떤 field 에 입력 시작
- Validation error 마주침
- 일부 field 만 채우고 abandon
2.1.1.2 Server roundtrip 없는 행동의 unique 가치
저자 강조: “What actions are done on the client without a server roundtrip? For example, there could be hovers generating help text or form field errors. Slideshows allow users to click and flip through slides, so capturing the times of those events is important.”
Client-only action 사례:
1. Tooltip:
- 사용자가 ? icon hover → tooltip 표시
- Server 무관 (client JavaScript)
- "사용자가 도움말 봤는가" signal 은 client only
2. Form validation:
- "Email 형식 잘못" 같은 client-side 검증
- Server 도달 안 함
- "사용자가 어떤 field 에서 error" signal 은 client only
3. Slideshow navigation:
- 사전 ship 된 slide 사이 이동
- Server 호출 없음
- "어떤 slide 에 머물렀나" signal 은 client only
4. Auto-suggest:
- 검색어 입력 중 suggestion 표시
- Server 호출 있을 수 있지만 사용자 행동 (hover, ignore) 은 client
- Conversion path 분석에 critical
이 행동들은 server 가 아예 모른다. Client 계측 없으면 사용자 의도·관심의 50% 정도 invisible.
2.1.1.3 영역 2 — Performance
저자 명시: “How long does it take the page (webpage or app page) to display or become interactive?”
2.1.1.4 Performance metrics 의 분류
Page load time:
- Server response 도달 시점
- 그러나 사용자 입장에서는 "보이는 시점" 이 중요
- Server 가 0.5초에 response 보냈어도 client rendering 1초 추가 가능
Time to first byte (TTFB):
- Browser 가 server 첫 byte 받은 시점
- Network latency 의 baseline
First Contentful Paint (FCP):
- 첫 의미 있는 콘텐츠 visible
- 사용자가 "page 도착" 인지하는 시점
Time to Interactive (TTI):
- 사용자가 actual interaction 가능한 시점
- JavaScript 가 모두 load + ready
- "click 가능" 인지 시점
Cumulative Layout Shift (CLS):
- Layout 이 흔들리는 정도
- 사용자 click 실수 빈도 의 indicator
저자는 Ch.5 (Speed Matters) 와 cross-reference: “we discuss the complexities around measuring the time from a search query request to displaying a full page.”
2.1.1.5 사용자 인지 vs server response
Server perspective:
Request 도착: t=0
Response 보냄: t=0.3s
→ Server 입장 "0.3 초"
Client perspective:
Request 보냄: t=0
TTFB: t=0.4s
FCP: t=0.7s
TTI: t=1.5s
→ 사용자 "1.5 초 기다림"
Gap 의 원인:
- Network latency
- Browser parsing
- JavaScript execution
- Asset (image, CSS) loading
server 만으로는 이 1.2 초 gap 가 invisible. 사용자 인지 latency 가 client 측정의 unique 가치.
2.1.1.6 영역 3 — Errors and Crashes
저자 명시: “JavaScript errors are common, and may be browser dependent, and it is critical to track errors and crashes in client software.”
2.1.1.7 Client error 의 다양성
Browser 별 차이:
- Chrome: 일부 API 지원
- Safari: 다른 일부
- IE/Edge: legacy API
- Firefox: 또 다른
같은 코드가 browser 별 다른 error 가능:
- JavaScript exception
- Network timeout
- Resource loading 실패
- CSS 호환성 문제
User device 별:
- Mobile vs Desktop
- Old OS vs New OS
- Slow CPU vs Fast CPU
2.1.1.8 Server 가 모르는 client error
Network failure:
- 사용자 network 끊김
- Request 가 client 에서 fail
- Server 도달 안 함
- Server 입장: 사용자 visit 자체 인지 못 함
- Client 만이 "사용자가 시도했지만 실패" 인지
JavaScript runtime error:
- Server 가 정상 HTML 응답
- Client JavaScript 가 일부 browser 에서 throw
- 사용자가 broken page 봄
- Server log 에는 정상으로 기록
- Client error reporting (Sentry, Rollbar) 필요
Memory leak:
- Long session 에 client memory 가 점차 증가
- 결국 browser tab crash
- Server 입장: session 끊김
- Client memory 추적 만이 root cause 발견
2.1.2 Client 계측의 4 가지 challenge — 깊이 있는 풀이
2.1.2.1 Challenge 1 — Performance Cost
저자 명시: “Client-side instrumentation can utilize significant CPU cycles and network bandwidth and deplete device batteries, impacting the user experience. Large JavaScript snippets will impact load time.”
JavaScript snippet 의 costs:
- 다운로드: 5~50 KB
- Parse + compile: 50~200 ms (low-end device)
- Execution: each event 마다 1~5 ms
- Network: each event 의 server 전송 (kbps 단위)
- Battery: cellular radio wake-up
2.1.2.2 Self-defeating 함정
계측이 너무 많으면:
- Page load 1 초 → 1.5 초 (50% 증가)
- 사용자 abandon rate ↑
- 측정하려는 metric (engagement) 자체 변화
→ 계측이 metric 을 변화시킴 (Heisenberg uncertainty 비유)
2.1.2.3 해결 — 계측 자체의 A/B 테스트
Treatment: full client instrumentation
Control: minimal client instrumentation
측정:
- 두 그룹의 engagement 차이 → 계측 의 cost
- 통계적 유의 → 계측 줄여야
이 메타-실험 자체가 가능. 계측 budget 의 정량 결정.
2.1.2.4 Challenge 2 — Web Beacon Lossiness
저자 인용 (Kohavi, Longbotham, Walker 2010).
2.1.2.5 Web beacon 의 메커니즘
일반적 web beacon:
사용자 click → JavaScript event handler
→ 1x1 pixel 의 tracking image 요청
→ image src URL 에 query parameter 로 event data
→ server 가 access log 에 기록 (image 자체는 무의미)
2.1.2.6 시나리오 a — Async Beacon 의 race condition
사용자 click "다음 page" link
↓
JavaScript: send beacon (async, 백그라운드)
JavaScript: navigate to next page (즉시)
↓
Browser:
- Next page 의 HTTP request 시작
- Current page 의 beacon 아직 전송 중
- Browser 가 이전 page 의 모든 connection 취소
- Beacon 손실
저자 강조: “The loss rate due to this race condition varies by browser.”
Browser 별 loss rate (대략):
Chrome: 5~10%
Firefox: 8~12%
Safari: 15~20%
Edge: 10~15%
2.1.2.7 시나리오 b — Sync Beacon 의 latency cost
대안: synchronous redirect
사용자 click
↓
JavaScript: send beacon (synchronous, 차단)
JavaScript: 응답 도착까지 대기
JavaScript: navigate to next page
장점: beacon 손실 ↓
단점: latency ↑ (200~500ms 추가)
→ 사용자 click abandonment ↑
→ "다음 page 너무 느려" 인지 + 이탈
2.1.2.8 시나리오 c — Application 별 trade-off
저자 강조: “ad clicks must be reliably tracked as they relate to payments and compliance requirements, b) is the preferred scenario even though there is added latency.”
Trade-off 결정:
Critical tracking (광고 click 등):
- Compliance requirement (광고주 결제)
- Loss 가 financial loss + 법적 risk
- Sync beacon 선택 (latency 받아들임)
Non-critical tracking (일반 user behavior):
- 분석 용도
- Loss 일부 허용 가능 (statistical sample)
- Async beacon 선택 (UX 우선)
Hybrid:
- Critical event sync, non-critical async
- Beacon 종류별 다른 정책
2.1.2.9 현대 대안 — Beacon API + Service Worker
저자 책 출판 (2020) 이후 개선:
navigator.sendBeacon (W3C 표준):
- Async 이지만 page unload 시도 보장
- Browser 가 beacon 을 background 에서 완료 보장
- Loss rate ↓ (~1~3%)
Service Worker:
- Background script
- 사용자 navigation 와 무관하게 beacon 전송
- Offline 시 queue 후 online 시 전송
이 도구들이 web beacon lossiness 를 거의 해결. 그러나 모든 browser 지원·구현 다름 → fallback 필요.
2.1.2.10 Challenge 3 — Client Clock 신뢰성
저자 명시: “Client clock can be changed, manually or automatically. This means that the actual timing from the client may not be fully synchronized with server time.”
2.1.2.11 Client clock 의 변동 원인
Manual:
- 사용자가 device timezone 변경
- 사용자가 의도적 시간 hack (게임 cooldown bypass 등)
- 사용자가 clock 수정 잊음 (몇 시간 ~ 며칠 차이)
Automatic:
- NTP sync 실패 (offline, firewall)
- Daylight saving time transition
- 시스템 update 시 일시적 변동
- Browser timezone API 의 inconsistency
2.1.2.12 Client time 의 부정확 정도
일반 사용자:
- 95% 가 server time 의 ±5 분 이내
- 4% 가 ±1 시간 이내
- 1% 가 1 시간 이상 차이
극단 case:
- 일부 사용자: 며칠 차이 (clock 수정 안 함)
- 일부 사용자: 미래 timestamp (의도적 manipulation)
2.1.2.13 분석 함의 — 저자 격언
저자 강조: “never subtract client and server times, as they could be significantly off even after adjusting for time zones.”
잘못된 분석:
Latency = client_event_time - server_log_time
→ 잘못된 결과 (음수, 너무 큰 값)
올바른 분석:
- Server time 만으로 latency
- 또는 client 의 monotonic clock (relative time)
- Client clock 의 absolute value 신뢰 안 함
2.1.2.14 Monotonic clock 의 활용
JavaScript 의 performance.now():
- 시작점 기준 ms 단위
- Wall clock 변경에 영향 안 받음
- Relative time 측정 신뢰 가능
용도:
- "Click 후 response 까지" relative duration
- Page load 의 단계별 timing
- 사용자 reaction time
이 monotonic clock 이 client 의 timing 분석의 기초. Wall clock 은 reference 만.
2.1.2.15 Challenge 4 — Data Accuracy
Client 계측 의 정확도 ↓ 원인:
1. Ad blocker:
- uBlock Origin 등이 tracking pixel 차단
- 일부 사용자의 모든 client event 손실
- 비율: 20~30% (geo·demo 별 다름)
2. Privacy mode (Incognito):
- Cookie 분리 → 같은 사용자가 다른 ID
- Session 종료 시 모든 state 초기화
3. User agent spoofing:
- 사용자가 browser identity 위조
- Bot detection 회피용
- Analytics 의 "user device" 부정확
4. Browser quirk:
- Browser 별 다른 event handling
- 일부 event 가 catch 안 됨
- Rare combination 에서 unexpected behavior
2.1.2.16 Client accuracy 의 정량
대략적 수치 (산업 평균):
모든 client event 의 server 도달:
- Web 모바일: ~70%
- Web 데스크톱: ~80%
- Native mobile app: ~85% (offline buffer 가능)
- Desktop app: ~90% (안정 환경)
즉 client 데이터는 항상 일정 비율 손실. 분석 시 이 손실 인지하고 server log 와 cross-validation.
2.2 Server-Side Instrumentation 의 시각
저자 강조: “Server-side instrumentation suffers less from these concerns. It offers a less clear view of what the user is actually doing but can provide more granularity of what is happening inside your system and why.”
2.2.1 Server 만이 보는 4 가지
2.2.1.1 1. Internal Algorithm Score
저자 사례: “In search engine results, there are internal scores indicating why specific search results were returned and their ranking.”
Search engine 의 internal scoring:
Query: "machine learning"
↓
Server 의 ranking 알고리즘:
Result 1 (Wikipedia): score = 0.95
- relevance: 0.92
- authority: 0.98
- freshness: 0.90
Result 2 (Coursera): score = 0.87
- relevance: 0.95
- authority: 0.85
- freshness: 0.80
Result 3 (Medium): score = 0.78
Client 만 보면:
- Result 1, 2, 3 만 보임
- 왜 그 순서인지 모름
Server 계측:
- 각 score 기록
- "왜 이 순서" 답 가능
- Algorithm 변경 시 cause-effect 분석
이 internal score 가 search engine debugging 의 본질. Client 만으로는 불가능.
2.2.1.2 2. Component-level Latency
저자 명시: “How long does it take for the server to generate the response, and which component takes the longest? What is the performance at the 99th percentile?”
Server response 의 latency 분해:
Total 응답 시간: 200ms
- Auth check: 5ms
- Database query: 80ms
- Cache lookup: 10ms
- Business logic: 50ms
- Template rendering: 30ms
- Serialization: 15ms
- Network (server → client): 10ms
Bottleneck: Database query (80ms = 40%)
Action: Query 최적화 또는 cache 추가
Client 만 보면: total latency 만 보임. Bottleneck 식별 불가.
2.2.1.3 3. System Internal State
Server 의 internal metrics:
Cache hit rate:
- L1 cache: 95% hit
- L2 cache: 80% hit
- 전체: 99% hit (good)
Connection pool:
- DB connection: 50/100 사용
- HTTP keep-alive: 30/50
Memory usage:
- Heap: 4GB / 8GB
- GC pause: 50ms (last)
Thread pool:
- Active threads: 200/500
- Queue: 0
이 metrics 가 시스템 health 의 가시성. 사용자 자각 전에 anomaly detect.
2.2.1.4 4. Variance — Lower Noise
저자 강조: “the data tend to have lower variance, allowing for more sensitive metrics.”
Client metric 의 noise 원인:
- 사용자 network (Wi-Fi vs cellular)
- Device 성능 (low-end vs flagship)
- Browser 차이
- 사용자 위치 (서버와 거리)
Server metric:
- 시스템 내부만 측정
- 외부 noise 없음
- 분산 ↓ → sensitivity ↑
2.2.1.5 Sample size requirement 비교
같은 effect 를 detect 하기 위한 N (가상 수치).
Client engagement metric (분산 큼):
Treatment effect 1% detect 위해: N = 100,000
Server response time (분산 작음):
Treatment effect 1% detect 위해: N = 5,000
20 배 sample size 차이. Server metric 으로 분석 가능한 영역은 server 우선 — 통계적 power 이득.
2.2.1.6 Server Synchronization 의 issue
저자 강조: “It is important to remember that servers also need to be synchronized often. There can be scenarios where the request is served by one server while the beacon is logged by another, creating a mismatch in timestamp.”
Distributed system 의 timestamp issue:
Server A: request 처리 (timestamp_A)
Server B: beacon log 기록 (timestamp_B)
Server A 와 Server B 의 clock skew:
- 보통 ms 단위 (NTP sync)
- 가끔 초 단위 (NTP failure)
분석:
- Same event 인데 timestamp 다름
- Latency 계산 시 음수 가능
해결:
- NTP sync 자주 (1 분 마다 check)
- 같은 event 의 모든 log 에 monotonic event_id
- Timestamp 의 absolute 값보다 event_id ordering 신뢰
두 시각의 보완은 다른 차원의 truth 를 본다.
2.2.1.7 사용자 click 의 두 시각 — 깊이 있는 풀이
사용자 click 의 full 시나리오:
t=0: 사용자가 "구매" 버튼 click 결정
t=10ms: Mouse 이동 + click event
t=15ms: Browser 의 click handler 실행
t=20ms: JavaScript 가 form 제출 시작
t=30ms: Web beacon 발사 (async)
t=40ms: Form data 의 HTTP POST 시작
t=50ms: TCP connection (네트워크)
t=80ms: Server 도달
t=120ms: Server 처리 시작
t=180ms: DB query 완료
t=200ms: Response 생성
t=220ms: Network return
t=250ms: Browser 가 next page 요청 시작
t=350ms: Server 가 next page 응답
t=500ms: Next page rendering 시작
t=700ms: 사용자가 next page 봄
이 700ms 시나리오의 두 시각:
2.2.1.8 Client 시각
- t=10ms: click 시점 (정확)
- t=500~700ms: next page rendering
- 사용자 인지 latency: 700ms
2.2.1.9 Server 시각
- t=80ms: request 도달
- t=200ms: response 보냄
- t=350ms: next page response
- Server 인지 latency: 120ms (process)
2.2.1.10 Joint 시각 (둘을 결합)
- t=10~80ms: client 측 + network (사용자 device 영향)
- t=80~200ms: server 처리 (system 영향)
- t=200~700ms: 다시 network + client rendering
- Total: client ~70%, server ~30%
이 분해가 latency optimization 의 핵심:
- Server 가 100ms ↓ 해도 total latency 700→650 (7% 개선)
- Client rendering 100ms ↓ 하면 total 700→600 (14% 개선)
따라서 latency 개선 priority 는 client first 가 자주 답. Server 만 보면 false priority.
이것이 양면 계측의 actionable insight. 한 면만 으로는 우선순위 결정 잘못.
2.2.1.11 다른 사례 — A/B 실험의 분석
Treatment: 새 search ranking 알고리즘
Server metric:
- Latency: 변화 없음
- Cache hit: 같음
- Internal score 분포: 변화 (의도)
Client metric:
- Click rate: -2%
- Time on result: +5%
- Return rate: +1%
Joint 결론:
- Server 입장: "변화 없음"
- Client 입장: "복잡한 패턴" (click ↓, time ↑)
- 통합 해석: "사용자가 더 careful 하게 result 평가"
- 의사결정: 새 알고리즘이 quality 측면 ↑ (click 보다 time 이 better signal)
이 통합 해석이 단일 시각으로는 불가. 양면 계측이 의사결정의 본질.
3 왜 필요한가
Client·Server 양면 계측 부재 시.
- Client only — 시스템 root cause 모름. Latency 증가 detect 해도 어떤 component 인지 모름. Internal algorithm score 부재 → debugging 불가.
- Server only — 사용자 actual experience 모름. Malware, JavaScript error, hover 등 invisible.
- 둘 다 부재 — 실험 자체 불가.
양면 계측 활성 시.
- Root cause 분석 — Client 의 사용자 영향 + Server 의 internal state 결합 → 정확한 debugging
- Sensitivity 균형 — Server (low variance) + Client (사용자 의 직접 측정) 의 best of both
- Cross-validation — 둘 사이 mismatch 자체가 signal (malware, network issue)
- Trustworthy 실험 — Multiple metric 으로 confounded effect 분리
이 격차가 platform maturity 의 큰 부분. 둘 다 잘하는 회사가 advanced.
4 응용 사례 — Search Engine 의 양면 계측
4.0.0.1 Bing/Google 의 search 분석
Server-side log:
- Query 도착 시점
- Ranking 알고리즘의 internal score (각 result)
- Database query latency
- Cache hit/miss
- 응답 보낸 시점
- Server ID (load balancing 분석)
Client-side log:
- 사용자 click 시점
- 어떤 result click (1st, 2nd, ...)
- Click 후 시간 (back to search vs stay)
- Hover 시간 (어떤 result 에 관심)
- Scroll depth (얼마나 봤는가)
- Time-to-click (사용자가 평가 시간)
4.0.0.2 Joint analysis 의 가치
Q1: "이 result 가 왜 사용자에 click 되었나?"
Server: "score 0.95, top ranked"
Client: "사용자가 0.5 초만 보고 click"
→ Result 의 title 이 attention catching
Q2: "사용자가 result 클릭 후 빠르게 돌아왔다. 왜?"
Server: "result page latency 5 초"
Client: "사용자가 4 초 후 back"
→ Result page 의 slowness 가 dissatisfaction
Q3: "Algorithm 변경의 효과?"
Server: "score 분포 변화"
Client: "click rate 변화 + time-on-result 변화"
→ Quality 효과 vs UX 효과 분리
이 3 질문 모두 양면 계측 의 결합 으로만 답 가능.
5 코드 예시 — Client·Server Latency 분해 분석
사용자 click 의 timing breakdown 시뮬레이션.
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
rng = np.random.default_rng(42)
n_clicks = 1000
# Client-side timing (사용자 입장)
client_data = []
for i in range(n_clicks):
click_id = f"click_{i:05d}"
click_time = datetime(2026, 5, 8, 10, 0) + timedelta(seconds=int(rng.uniform(0, 3600)))
client_data.append({
"click_id": click_id,
"client_click_time": click_time,
"client_perf_now_ms": rng.uniform(0, 1000), # monotonic clock
})
client_df = pd.DataFrame(client_data)
# Server-side timing
server_data = []
for i in range(n_clicks):
click_id = f"click_{i:05d}"
# Network latency client → server
network_to_server_ms = rng.lognormal(3, 0.5)
# Server processing time
server_processing_ms = rng.lognormal(4, 0.3)
# Network back
network_back_ms = rng.lognormal(3, 0.5)
server_data.append({
"click_id": click_id,
"server_received_at": client_df.iloc[i]["client_click_time"] +
timedelta(milliseconds=int(network_to_server_ms)),
"network_to_server_ms": network_to_server_ms,
"server_processing_ms": server_processing_ms,
"network_back_ms": network_back_ms,
})
server_df = pd.DataFrame(server_data)
# 통합
merged = client_df.merge(server_df, on="click_id")
# Total latency = network_to_server + server_processing + network_back
merged["total_latency_ms"] = (
merged["network_to_server_ms"] +
merged["server_processing_ms"] +
merged["network_back_ms"]
)
# 분포 분석
print("=== Latency 분해 (ms) ===")
print(f"Network to server: mean={merged['network_to_server_ms'].mean():.1f}, "
f"p99={merged['network_to_server_ms'].quantile(0.99):.1f}")
print(f"Server processing: mean={merged['server_processing_ms'].mean():.1f}, "
f"p99={merged['server_processing_ms'].quantile(0.99):.1f}")
print(f"Network back: mean={merged['network_back_ms'].mean():.1f}, "
f"p99={merged['network_back_ms'].quantile(0.99):.1f}")
print(f"Total: mean={merged['total_latency_ms'].mean():.1f}, "
f"p99={merged['total_latency_ms'].quantile(0.99):.1f}")
# Bottleneck 식별
mean_breakdown = pd.Series({
"Network to server": merged["network_to_server_ms"].mean(),
"Server processing": merged["server_processing_ms"].mean(),
"Network back": merged["network_back_ms"].mean(),
})
total_mean = mean_breakdown.sum()
breakdown_pct = (mean_breakdown / total_mean * 100).round(1)
print(f"\n=== Bottleneck 분석 ===")
print(breakdown_pct.to_string())
print(f"\nMain bottleneck: {breakdown_pct.idxmax()} ({breakdown_pct.max():.1f}%)")
# 만약 server processing 만 보면? (server-only 분석)
print(f"\n=== Server-only 분석 (Client 없으면) ===")
print(f"Average latency: {merged['server_processing_ms'].mean():.1f}ms")
print(f"Conclusion: System fast, no problem")
# Client-side total latency 봤을 때?
print(f"\n=== Client-side 분석 (Server 없으면) ===")
print(f"User-perceived latency: {merged['total_latency_ms'].mean():.1f}ms")
print(f"Conclusion: Slow, but where? 모름.")
# Joint 분석
print(f"\n=== Joint 분석 ===")
network_total_pct = (merged["network_to_server_ms"].mean() +
merged["network_back_ms"].mean()) / total_mean * 100
print(f"Network 비중: {network_total_pct:.1f}%")
print(f"Server 비중: {breakdown_pct['Server processing']:.1f}%")
if network_total_pct > 60:
print(f"Action: CDN 추가, edge 배포로 network latency 줄임")
else:
print(f"Action: Server processing 최적화 우선")예상 출력 (시드 42).
=== Latency 분해 (ms) ===
Network to server: mean=22.7, p99=67.4
Server processing: mean=57.2, p99=109.3
Network back: mean=22.7, p99=67.0
Total: mean=102.6, p99=224.1
=== Bottleneck 분석 ===
Network to server 22.1
Server processing 55.7
Network back 22.1
dtype: float64
Main bottleneck: Server processing (55.7%)
=== Server-only 분석 (Client 없으면) ===
Average latency: 57.2ms
Conclusion: System fast, no problem
=== Client-side 분석 (Server 없으면) ===
User-perceived latency: 102.6ms
Conclusion: Slow, but where? 모름.
=== Joint 분석 ===
Network 비중: 44.3%
Server 비중: 55.7%
Action: Server processing 최적화 우선
이 시뮬레이션의 4 가지.
1. Server-only 분석의 함정
Server perspective: "Latency 57ms, fast"
사용자 perspective: "Latency 103ms, slow"
사용자가 인지하는 latency 가 server processing time 의 거의 2 배. Server 만 보면 false sense of speed.
2. Client-only 분석의 한계
Client perspective: "103ms, slow"
하지만 어디서 slow 인지 모름.
- Network 문제? Server 문제? Client rendering 문제?
- Action 결정 불가
Client 만 보면 user-perceived 만 알지만 root cause 모름.
3. Joint 분석의 Actionable Insight
Joint: "Network 44%, Server 56%"
- Server processing 가 dominant
- Server-side 최적화 우선
추가 정보:
- Mobile cellular vs Wi-Fi 별 다름?
- 특정 region 의 network 비중 ↑?
- Peak hour 의 server bottleneck?
이 추가 분석이 모두 양면 계측 의 결합 으로만 가능.
4. Optimization Priority 의 정량 결정
Investment 옵션:
A) Server CPU 추가 (server processing -20ms)
→ Total: 103 - 20 = 83ms
→ 19% 개선
B) CDN/Edge 추가 (network -15ms 양방향 = -30ms)
→ Total: 103 - 30 = 73ms
→ 29% 개선
이 분석 없이는:
- Server team: "우리 system 이 main"
- Network team: "network 가 main"
- Argument 만 발생, decision 어려움
양면 계측의 정량 분석:
- 객관적 priority 결정
- ROI 기반 investment
이 정량 결정이 양면 계측의 본질적 가치. Argument 가 아닌 evidence-based decision.
6 관련 주제
선행
다음 글
관련 챕터
- F5-* — Ch.5 Speed Matters — Latency 의 사용자 영향
- F12-1 — Server vs Client 차이 — Mobile 특화
다른 카테고리 연결
- Engineering — Web Beacon API · sendBeacon
- Engineering — APM (Application Performance Monitoring) — New Relic, Datadog, Dynatrace
- Engineering — Distributed Tracing — OpenTelemetry, Jaeger, Zipkin