Workspace IndexAlgorithms › Day 49

Capacity Planning, SLOs, and Error Budgets TODO

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

Concept

An SLO is a target set on a service-level indicator (SLI) measured from the user's perspective, and the error budget is the total amount of failure that target allows. If the availability target is set at 99.9%, the remaining 0.1% is the budget available for that period, and it becomes an explicit trade-off mechanism between shipping speed and stability. When budget remains you can deploy more aggressively; once it's exhausted, the policy is to halt feature releases and put the effort into reliability work instead. Capacity planning combines this with load forecasting to determine the maximum load the system can absorb while holding the target latency, and how much headroom is needed. From a queuing-theory perspective, wait time diverges sharply as utilization approaches 1, so headroom should be sized against peak and tail load, not average utilization.

Without agreeing on "how stable does this need to be" as a number, every priority fight between incident response and feature work turns into an emotional argument.

Code & Formula

# 용량 계획·SLO와 에러 예산 — 가용성 목표에서 허용 실패량(에러 예산)을 계산하고,
# 실측 실패율로 예산 소진율을 구해 배포를 계속할지 판단한다.

def error_budget_minutes(slo_percent, period_days=30):
    """기간 동안 허용되는 다운타임(분)"""
    period_minutes = period_days * 24 * 60
    allowed_failure_ratio = 1 - slo_percent / 100
    return period_minutes * allowed_failure_ratio

def budget_status(slo_percent, downtime_minutes_so_far, days_elapsed, period_days=30):
    total_budget = error_budget_minutes(slo_percent, period_days)
    consumed_ratio = downtime_minutes_so_far / total_budget
    # 지금까지 경과한 기간 대비 정상 소진 속도(1.0이면 딱 예산대로 소진 중)
    expected_ratio_by_now = days_elapsed / period_days
    burn_rate = consumed_ratio / expected_ratio_by_now if expected_ratio_by_now else 0
    return total_budget, consumed_ratio, burn_rate

slo = 99.9  # 월 가용성 목표
total_budget = error_budget_minutes(slo)
print(f"SLO {slo}% -> 30일 에러 예산: {total_budget:.1f}분")

scenarios = [
    ("정상 운영", 10.0, 15),   # 15일 경과, 다운타임 10분
    ("장애 다발", 35.0, 15),   # 같은 15일에 다운타임 35분
]

for name, downtime, days in scenarios:
    budget, consumed, burn = budget_status(slo, downtime, days)
    action = "배포 계속 (여유 있음)" if burn < 1.0 else "기능 출시 중단, 신뢰성 작업 우선"
    print(f"[{name}] {days}일 경과, 다운타임 {downtime}분 -> "
          f"소진율 {consumed*100:.1f}%, burn rate {burn:.2f}x -> {action}")

# 용량 계획: 이용률이 1에 가까워질수록 대기시간이 급격히 발산 (M/M/1 근사)
def expected_wait_factor(utilization):
    """대기행렬 이론: 대기시간은 rho / (1 - rho) 에 비례해 발산"""
    if utilization >= 1:
        return float("inf")
    return utilization / (1 - utilization)

print("\n이용률별 대기시간 배율 (M/M/1 근사):")
for rho in [0.5, 0.7, 0.9, 0.95, 0.99]:
    print(f"  rho={rho:.2f} -> wait factor={expected_wait_factor(rho):.2f}")

Exercise

For a service you run, define two SLIs (availability and p99 latency), compute a 30-day SLO and error budget, then plug in the last 30 days of real measurements to work out the budget burn rate.

Practical Connection

For paths mixed with external factors — RPC node dependencies, oracle response latency, settlement transaction confirmation time — pre-defining targets and budgets is what lets you judge where "normal" ends.

Where it lands in Jayverse

Key expressions

Words and phrases from this page worth keeping, with the Korean meaning and the sentence they come from.

Expression뜻 · 쓰이는 자리
error budget오류 예산(허용 가능한 장애 총량) · SLO에서 남은 실패 허용치를 가리킬 때 · "the error budget is the total amount of failure"
burn rate소진 속도 · 오류 예산이 얼마나 빨리 소모되는지 측정할 때 · "work out the budget burn rate"
headroom여유 용량 · 최대 부하 대비 시스템이 가진 여분을 가리킬 때 · "how much headroom is needed"
tail load꼬리 부하(피크·극단적으로 몰리는 부하) · 평균이 아니라 극단치 기준으로 설계할 때 · "headroom should be sized against peak and tail load"
diverges sharply급격히 발산하다·치솟다 · 이용률이 100%에 가까워질 때 대기시간이 폭증하는 현상 · "wait time diverges sharply as utilization approaches 1"
halt feature releases기능 출시를 중단하다 · 오류 예산이 소진되면 취하는 정책 · "the policy is to halt feature releases"
put the effort into~에 노력을 쏟다 · 안정성 작업으로 자원을 돌릴 때 · "put the effort into reliability work instead"
SLO서비스 수준 목표(Service-Level Objective) · SLI에 대해 설정하는 목표치, 오류 예산 산정의 기준 · "An SLO is a target set on a service-level indicator (SLI)"
SLI서비스 수준 지표(Service-Level Indicator) · 사용자 관점에서 측정하는 지표, SLO가 목표로 삼는 값 · "a service-level indicator (SLI) measured from the user's perspective"

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/.


한국어

용량 계획·SLO와 에러 예산 TODO

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

개념

SLO는 사용자 관점의 서비스 수준 지표(SLI)에 대해 정한 목표치이고, 에러 예산은 그 목표가 허용하는 실패의 총량이다. 가용성 목표를 99.9%로 잡았다면 나머지 0.1%가 한 기간 동안 쓸 수 있는 예산이며, 이 예산은 배포 속도와 안정성 사이의 명시적 교환 수단이 된다. 예산이 남으면 더 공격적으로 배포하고, 소진되면 기능 출시를 멈추고 신뢰성 작업에 투입하는 식의 정책으로 운영한다. 용량 계획은 여기에 부하 예측을 결합해, 목표 지연시간을 유지한 채 소화 가능한 최대 부하와 필요한 여유분을 정하는 작업이다. 대기행렬 관점에서 이용률이 1에 가까워질수록 대기시간이 급격히 발산하므로, 평균 이용률이 아니라 피크와 꼬리를 기준으로 여유를 잡아야 한다.

"얼마나 안정적이어야 하는가"를 숫자로 합의해 두지 않으면 장애 대응과 기능 개발의 우선순위 다툼이 매번 감정 싸움이 된다.

코드 · 수식

# 용량 계획·SLO와 에러 예산 — 가용성 목표에서 허용 실패량(에러 예산)을 계산하고,
# 실측 실패율로 예산 소진율을 구해 배포를 계속할지 판단한다.

def error_budget_minutes(slo_percent, period_days=30):
    """기간 동안 허용되는 다운타임(분)"""
    period_minutes = period_days * 24 * 60
    allowed_failure_ratio = 1 - slo_percent / 100
    return period_minutes * allowed_failure_ratio

def budget_status(slo_percent, downtime_minutes_so_far, days_elapsed, period_days=30):
    total_budget = error_budget_minutes(slo_percent, period_days)
    consumed_ratio = downtime_minutes_so_far / total_budget
    # 지금까지 경과한 기간 대비 정상 소진 속도(1.0이면 딱 예산대로 소진 중)
    expected_ratio_by_now = days_elapsed / period_days
    burn_rate = consumed_ratio / expected_ratio_by_now if expected_ratio_by_now else 0
    return total_budget, consumed_ratio, burn_rate

slo = 99.9  # 월 가용성 목표
total_budget = error_budget_minutes(slo)
print(f"SLO {slo}% -> 30일 에러 예산: {total_budget:.1f}분")

scenarios = [
    ("정상 운영", 10.0, 15),   # 15일 경과, 다운타임 10분
    ("장애 다발", 35.0, 15),   # 같은 15일에 다운타임 35분
]

for name, downtime, days in scenarios:
    budget, consumed, burn = budget_status(slo, downtime, days)
    action = "배포 계속 (여유 있음)" if burn < 1.0 else "기능 출시 중단, 신뢰성 작업 우선"
    print(f"[{name}] {days}일 경과, 다운타임 {downtime}분 -> "
          f"소진율 {consumed*100:.1f}%, burn rate {burn:.2f}x -> {action}")

# 용량 계획: 이용률이 1에 가까워질수록 대기시간이 급격히 발산 (M/M/1 근사)
def expected_wait_factor(utilization):
    """대기행렬 이론: 대기시간은 rho / (1 - rho) 에 비례해 발산"""
    if utilization >= 1:
        return float("inf")
    return utilization / (1 - utilization)

print("\n이용률별 대기시간 배율 (M/M/1 근사):")
for rho in [0.5, 0.7, 0.9, 0.95, 0.99]:
    print(f"  rho={rho:.2f} -> wait factor={expected_wait_factor(rho):.2f}")

연습

운영 중인 서비스 하나에 대해 SLI 두 개(가용성·p99 지연)를 정의하고 30일 SLO와 에러 예산을 계산한 뒤, 지난 30일 실측을 대입해 예산 소진율을 구해 보기.

실무 · Verex 연결

RPC 노드 의존, 오라클 응답 지연, 정산 트랜잭션 확정 시간처럼 외부 요인이 섞인 경로일수록 목표와 예산을 미리 정해 두어야 어디까지가 정상인지 판단할 수 있다.

Jayverse에서의 위치

핵심 표현

이 페이지의 영어 본문에서 배울 만한 단어와 표현, 뜻과 나온 자리.

Expression뜻 · 쓰이는 자리
error budget오류 예산(허용 가능한 장애 총량) · SLO에서 남은 실패 허용치를 가리킬 때 · "the error budget is the total amount of failure"
burn rate소진 속도 · 오류 예산이 얼마나 빨리 소모되는지 측정할 때 · "work out the budget burn rate"
headroom여유 용량 · 최대 부하 대비 시스템이 가진 여분을 가리킬 때 · "how much headroom is needed"
tail load꼬리 부하(피크·극단적으로 몰리는 부하) · 평균이 아니라 극단치 기준으로 설계할 때 · "headroom should be sized against peak and tail load"
diverges sharply급격히 발산하다·치솟다 · 이용률이 100%에 가까워질 때 대기시간이 폭증하는 현상 · "wait time diverges sharply as utilization approaches 1"
halt feature releases기능 출시를 중단하다 · 오류 예산이 소진되면 취하는 정책 · "the policy is to halt feature releases"
put the effort into~에 노력을 쏟다 · 안정성 작업으로 자원을 돌릴 때 · "put the effort into reliability work instead"
SLO서비스 수준 목표(Service-Level Objective) · SLI에 대해 설정하는 목표치, 오류 예산 산정의 기준 · "An SLO is a target set on a service-level indicator (SLI)"
SLI서비스 수준 지표(Service-Level Indicator) · 사용자 관점에서 측정하는 지표, SLO가 목표로 삼는 값 · "a service-level indicator (SLI) measured from the user's perspective"

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

← 1101. 분산 트레이싱과 샘플링 전략1103. 카오스 엔지니어링·장애 주입 설계 →