Workspace IndexAlgorithms › Day 51

[Review] Writing a Performance Budget Document TODO

Algorithms · Day 51 / 100 · C. Concurrency & Performance Engineering (Day 36-51)

Concept

A performance budget document spells out, in numbers and conditions, the performance targets a system must meet, serving as the basis for design, review, and deployment decisions. At minimum it needs the target workload (request types and their ratios), the load level (requests per second, concurrency), metrics and targets (tail latency like p95/p99 rather than average, throughput, resource usage), and the measurement method and environment — that's what makes it a reproducible baseline. The budget becomes far more actionable when the overall target is broken down and allocated across segments — for example, splitting an end-to-end latency target across network, queue wait, handler, and DB call lets you immediately see which segment blew its budget. Targets should be set with justification; deriving them from user-perceived thresholds or an upstream system's timeout is more defensible than picking arbitrary numbers. Finally, the document only carries real force once it also states what happens on a budget overrun — blocking deployment, rolling back, an exception-approval process.

Without a documented target, performance turns into a subjective argument over "slow" versus "fast," and regressions only get discovered once they've piled up, by which point tracing the cause is hard.

Code & Formula

# [복습] 성능 예산 문서 쓰기 — 종단 지연 목표를 구간별(네트워크/큐/핸들러/DB)로 쪼개
# 각 구간 상한을 정하고, 실측값과 비교해 어느 구간이 예산을 초과했는지 즉시 드러낸다.

budget_ms = {
    "network": 20,
    "queue_wait": 30,
    "handler": 40,
    "db_call": 50,
}
total_budget_ms = sum(budget_ms.values())

# 실측치 두 세트: 정상 배포 vs 회귀가 있는 배포
measured_ok = {"network": 18, "queue_wait": 25, "handler": 35, "db_call": 45}
measured_regressed = {"network": 19, "queue_wait": 28, "handler": 38, "db_call": 95}

def evaluate(name, measured):
    print(f"--- {name} (총 예산 {total_budget_ms}ms) ---")
    violations = []
    for stage, limit in budget_ms.items():
        actual = measured[stage]
        status = "OK" if actual <= limit else "OVER"
        if status == "OVER":
            violations.append(stage)
        print(f"  {stage:10s}: {actual:5.1f}ms / {limit}ms budget -> {status}")
    total_actual = sum(measured.values())
    print(f"  합계: {total_actual:.1f}ms / {total_budget_ms}ms")
    if violations:
        print(f"  조치: 배포 차단 (초과 구간: {', '.join(violations)})")
    else:
        print("  조치: 배포 승인")
    print()

evaluate("정상 배포", measured_ok)
evaluate("회귀가 있는 배포", measured_regressed)

Exercise

Pick one of the services you currently work on, write a one-page budget covering workload, load, per-segment latency budget, measurement method, and action-on-overrun, then fill in actual measurements next to each line to find current violations.

Practical Connection

Breaking Verex's path from order submission to fill reflected — API, matching, chain submission, confirmation wait — into per-segment budgets lets you immediately tell, when perceived latency worsens, whether it's chain congestion or a regression in your own service.

If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/dev-100-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.


한국어

[복습] 성능 예산 문서 쓰기 TODO

Algorithms · Day 51 / 100 · C. 동시성·성능 엔지니어링 (Day 36–51)

개념

성능 예산 문서는 시스템이 지켜야 할 성능 목표를 숫자와 조건으로 명시해 설계·리뷰·배포 판단의 기준으로 삼는 문서다. 최소한 대상 워크로드(요청 종류와 비율), 부하 수준(초당 요청 수, 동시성), 지표와 목표치(평균이 아니라 p95·p99 같은 꼬리 지연, 처리량, 자원 사용량), 측정 방법과 환경이 들어가야 재현 가능한 기준이 된다. 예산은 전체 목표를 구간별로 쪼개 배분할 때 실효성이 커지는데, 예를 들어 종단 지연 목표를 네트워크·큐 대기·핸들러·DB 호출로 나누어 각 구간의 상한을 정하면 어느 구간이 예산을 초과했는지 바로 드러난다. 목표치는 근거 있게 정해야 하며, 사용자 체감이나 상류 시스템의 타임아웃처럼 외부 제약에서 역산하는 것이 임의로 정한 숫자보다 방어 가능하다. 마지막으로 예산 초과 시의 행동(배포 차단, 롤백, 예외 승인 절차)까지 적어야 문서가 실제로 구속력을 갖는다.

성능은 목표가 문서화되어 있지 않으면 '느리다/빠르다'는 주관적 논쟁이 되고, 회귀가 누적된 뒤에야 발견되어 원인 추적이 어려워진다.

코드 · 수식

# [복습] 성능 예산 문서 쓰기 — 종단 지연 목표를 구간별(네트워크/큐/핸들러/DB)로 쪼개
# 각 구간 상한을 정하고, 실측값과 비교해 어느 구간이 예산을 초과했는지 즉시 드러낸다.

budget_ms = {
    "network": 20,
    "queue_wait": 30,
    "handler": 40,
    "db_call": 50,
}
total_budget_ms = sum(budget_ms.values())

# 실측치 두 세트: 정상 배포 vs 회귀가 있는 배포
measured_ok = {"network": 18, "queue_wait": 25, "handler": 35, "db_call": 45}
measured_regressed = {"network": 19, "queue_wait": 28, "handler": 38, "db_call": 95}

def evaluate(name, measured):
    print(f"--- {name} (총 예산 {total_budget_ms}ms) ---")
    violations = []
    for stage, limit in budget_ms.items():
        actual = measured[stage]
        status = "OK" if actual <= limit else "OVER"
        if status == "OVER":
            violations.append(stage)
        print(f"  {stage:10s}: {actual:5.1f}ms / {limit}ms budget -> {status}")
    total_actual = sum(measured.values())
    print(f"  합계: {total_actual:.1f}ms / {total_budget_ms}ms")
    if violations:
        print(f"  조치: 배포 차단 (초과 구간: {', '.join(violations)})")
    else:
        print("  조치: 배포 승인")
    print()

evaluate("정상 배포", measured_ok)
evaluate("회귀가 있는 배포", measured_regressed)

연습

지금 다루는 서비스 중 하나를 골라 워크로드·부하·구간별 지연 예산·측정 방법·초과 시 조치를 한 페이지로 적고, 실제 측정값을 옆 칸에 채워 현재 위반 항목을 찾아보라.

실무 · Verex 연결

Verex의 주문 제출부터 체결 반영까지를 API·매칭·체인 제출·확정 대기로 나누어 각 구간 예산을 잡아 두면, 체감 지연이 나빠졌을 때 체인 혼잡 탓인지 자체 서비스 회귀인지 즉시 구분할 수 있다.

공부한 날 원본 커리큘럼(docs/knowledge/dev-100-curriculum.md)의 이 줄에 노트 링크와 ✅ 를 붙이면, 이 자리는 노트 본문으로 바로 이어집니다. 노트 없이 이 페이지에 바로 적어도 됩니다 — 다만 다시 생성하면 덮어쓰이므로, 남길 글은 docs/algorithms/ 의 마크다운으로 쓰는 편이 안전합니다.

← 50. 카오스 엔지니어링·장애 주입 설계52. 일관성 모델 지도 →