🎧 ▶ 5분 브리핑으로 듣기
▶ 오디오북 재생 (Google Drive)
NotebookLM 오디오 개요 (AI 생성)
📕 전자책 전문 읽기 오류 예산 · 31쪽
브라우저가 PDF를 바로 표시하지 못합니다. 새 탭에서 열기
이 글은 요약해 다시 쓴 것이고, PDF가 전문입니다.

혼자 프로덕션을 돌리는 개발자를 위한 글이고 끝까지 읽으면 ‘오늘 밤에 올릴까, 지켜볼까’를 기분과 추측의 영역에서 빼는 숫자 세트를 손에 쥘 수 있습니다. 답부터 말하자면, 그 숫자는 에러 버짓입니다.

‘더 안정적으로 만들어라’는 멈춤 점이 없는 목표입니다. 하나를 고치면 둘이 보이고 둘을 고치면 셋이 보입니다. 문제는 노력이 부족해서가 아닙니다. ‘얼마나 안정적이면 충분한가’에 답이 없기 때문입니다. 답이 없으면 모든 선택은 추측이 되고 추측은 새벽 2시에 값을 치릅니다.

이 글은 한 주장을 처음부터 끝까지 논증합니다. 약속을 숫자로 적는 순간, 안정성은 끝없는 목표에서 유한한 한계로 바뀝니다. 운영 판단은 산술이 됩니다. 그 숫자의 이름이 SLO이고 남는 여분이 에러 버짓이며 쓰는 속도가 연소율입니다.

에러 버짓을 쓰면 판단이 산술이 된다 개념을 형상화한 이미지 글의 핵심 개념을 형상화했습니다.

멈춤 점이 없는 목표

안정성에는 특별한 성질이 있습니다. 아무리 잘해도 ‘더 안정적’은 언제나 가능해 보입니다. 그래서 ‘더 안정적으로 만들어라’는 지시는 끝이 없어 보이고, 솔로 개발자에게는 지시자가 대체로 자기 자신이라 그 끝없음을 남에게 돌릴 수도 없습니다.

이 글의 관점은 다릅니다. 막막한 이유는 ‘충분한 안정성’이 정의되지 않았기 때문입니다. 정의가 없으면 밤마다 새로 결정을 내립니다. 오늘 밤에 새 기능을 올릴까요, 아니면 모니터링에 밤을 쓸까요. 이 두 선택 사이에는 숫자가 없고 따라서 근거도 없습니다.

근거가 없는 결정은 추측입니다. 추측이 틀리면 새벽 2시에 값을 치릅니다. 프로덕션이 깨진 채로 깨닫거나, 롤백에 밤을 다 쓰거나, 둘 다인 경우도 있습니다. 에러 버짓은 이 추측의 구조에 값을 치르게 하는 문제를 없애기 위한 도구입니다. 방법은 단순합니다. ‘이 서비스는 한 달의 99.9퍼센트 동안 사용자에게 동작한다’는 한 줄을 쓰는 것입니다.

그 한 줄은 마케팅 문구가 아닙니다. 시스템 주위에 긋는 선입니다. 이 선은 다음 시간을 어디에 쓸지와 쓰지 않을지를 정합니다. 선 안쪽의 노력이 안정화이고 선 밖의 노력이 기능이 되는 것은 이 선이 있을 때만 성립합니다. 이 글은 그 선을 긋는 순서와, 선이 만들어낸 숫자로 판단하는 법을 끝까지 논증합니다.

선이 없으면 전략은 두 개뿐입니다. 서둘러 기능을 올리고 깨지면 고치거나, 영원히 더 안정화하다가 기능을 못 올리거나요. 둘 다 밤의 고민을 줄이지 못합니다. 에러 버짓이 주는 세 번째 길은 ‘선을 먼저 긋고, 선까지 안정화한 뒤, 그 안에서 기능 경쟁력을 키운다’는 것입니다. 방향이 정해지면 밤의 고민은 줄어듭니다.

핵심 개념 요약 인포그래픽 1 NotebookLM이 소스를 종합해 생성한 인포그래픽입니다.

사용자를 재는 숫자부터

숫자를 쓰기 전에 순서가 있습니다. 사용자가 무엇을 느끼는지 정하고 그것을 재는 숫자를 고르고 그다음에 선을 긋습니다. 이 순서는 바꿀 수 없습니다. 선을 먼저 긋게 되면 재기 쉬운 숫자를 고르게 되고, 계약은 사용자의 경험에서 서버의 상태 쪽으로 미끄러집니다.

재는 대상을 사용자로 한정하는 이유는 단순합니다. 서버가 아무리 건강해도 사용자가 저장을 못 하면 실패입니다. 반대로 서버에 경고가 쏟아져도 사용자가 아무것도 느끼지 못하면, 그것은 내 안도감 문제일 뿐입니다. 그래서 SLI, 서비스 레벨 지표는 ‘응답이 200 상태 코드를 반환한 요청의 비율’처럼 사용자가 느끼는 경험을 재야 합니다.

‘CPU 사용률이 80퍼센트 이하인 서버의 비율’도 숫자입니다. 하지만 이것은 내부의 안도감입니다. 전자는 사용자에게 드리는 약속이고 후자는 나 혼자 쓰는 안정제입니다. 둘을 바꿔치기하면 SLO는 형식 그대로 99.9퍼센트를 유지하면서 실질적으로 아무것도 보장하지 않게 됩니다.

핵심 SLI를 고르는 방법은 실용적입니다. 서버를 잠시 치워 두고 사용자가 내 서비스로 실제로 하는 동작을 적습니다. 메모 앱이라면 열고 쓰고 저장합니다. 사진 공유 서비스라면 올리고 봅니다. API라면 파트너가 불러서 올바른 답을 받습니다. 이 동작 가운데 실패했을 때 손실이 가장 큰 순간을 고르면, 그것이 핵심 SLI의 후보가 됩니다.

메모 앱에서 저장이 안 되는 순간이 죽는 순간입니다. 여는 것이 약간 느린 것은 짜증나는 것이지 죽는 것은 아닙니다. 그래서 핵심은 ‘저장 요청이 성공한 비율’이 되고, 전체 응답 속도는 되지 않습니다. 동작 하나하나에 ‘이것이 실패하면 사용자는 무엇을 잃는가’를 한 줄씩 적어 보면, 목록은 보통 짧습니다. 계약이 짧다는 것은 특징입니다.

재는 숫자의 종류는 대략 네 가지로 나눌 수 있습니다. 가용성, 즉 동작했습니까. 지연, 즉 얼마나 빠르게 동작했습니까. 정확성, 즉 답이 맞았습니까. 신선도, 즉 데이터가 얼마나 새로운가요. 대부분의 서비스는 가용성에서 시작하지만 성격에 따라 무게가 달라집니다. 검색 서비스는 요청이 성공했는데 답이 틀리면 실패입니다. 뉴스 피드는 답이 맞는데 하루가 지났으면 실패입니다. 핵심 SLI가 둘셋이 되는 것은 가능하지만 각각은 ‘이것은 어떤 손실에 대응하는가’에 답해야 합니다. 답이 없으면 보조 지표고 보조 지표로는 계약을 지어서는 안 됩니다.

43분의 한계

SLO를 긋고 나면 손에 한 달 치 실패 허용량이 생깁니다. SLO가 99.9퍼센트이고 창이 한 달이라면, 허용 실패는 한 달의 0.1퍼센트입니다. 한 달을 30일로 잡으면 시간으로 환산해 약 43분입니다. 이 43분이 에러 버짓입니다.

이 숫자가 주는 첫 번째 효과는, 안정성이 체감 가능한 크기가 된다는 것입니다. ‘더 안정적으로’는 무한대였습니다. ‘이 달의 실패를 43분 안에 넣어라’는 유한합니다. 유한한 한계는 재고 비교하고 계획할 수 있습니다. 추측은 여기서 한 번 멈춥니다.

두 번째 효과는 단위 변환입니다. SLI가 요청 단위라면 버짓은 시간 말고 개수로도 쓸 수 있습니다. 한 달 요청이 10만 건이고 SLO가 99.9퍼센트라면 허용 실패는 한 달에 100건입니다. 하루는 약 3건, 일주는 약 23건입니다. 대시보드에 ‘오늘 오류 12건’이 뜨면, 이것은 ‘하루에 나흘 치 버짓을 쓴’이라는 문장이 됩니다.

한 가지를 엄밀하게 짚어야 합니다. 이 숫자는 ‘얼마나 실패할 것인가’의 예측이 아닙니다. ‘얼마까지 실패해도 되는가’의 한계입니다. 전자는 기대치이고 후자는 한계선입니다. ‘버짓이니까 조금은 깨도 된다’는 마음으로 쓰면 안 됩니다. 버짓은 실패가 한계를 넘는 순간을 알아볼 수 있게 하는 장치입니다.

한계로 읽히기 시작하면 행동이 달라집니다. 43분 안에 들어가면 손을 놓고 벗어나면 원인을 보고 연속으로 벗어나면 올림을 멈춥니다. 같은 ‘오류가 났다’ 상황인데, 버짓이 남아 있으면 일과이고 버짓이 없으면 사건입니다. 이 구분이 ‘심각한가’라는 새벽 2시 질문의 절반을 대신 답합니다.

지금의 심각도는 연소율이다

한 달 합계로는 매일 부딪히는 질문에 답이 안 됩니다. 그 질문은 ‘지금 일어나는 이 실패가 심각한가’입니다. 한 달짜리 버짓은 느립니다. 실패가 달 중반에 몰려도, 합계로 보면 아직 멀쩡해 보입니다. 이 느림을 고치는 지표가 연소율입니다.

연소율은 버짓을 소진하는 속도를 배수로 쓴 것입니다. 기준은 1배입니다. 1배로 쓰면 한 달 마지막에 버짓이 정확히 0이 됩니다. 급한 일은 아니지만 그 달은 붉게 끝납니다. 10배로 쓰면 이야기는 완전히 달라집니다. 버짓은 약 3일로 다 소진됩니다. 더 이상 한 달의 문제가 아닙니다. 지금 이 순간 서비스가 깨지고 있다는 문제입니다.

연료 계정에 비유할 수 있습니다. 1배 연소는 장거리 주행을 하며 천천히 줄어드는 휘발유입니다. 문제없어 보입니다. 10배 연소는 탱크가 새고 있다는 신호입니다. 게이지가 아직 절반을 가리키더라도, 새는 속도로 보면 오늘 안에 고장이 납니다. 에러 버짓도 마찬가지입니다. 잔량은 남은 시간의 함수입니다.

숫자로 다시 보면, 1배는 하루에 43분의 30분의 1, 약 1분 남짓을 쓰는 속도입니다. 10배는 하루 약 14분입니다. 같은 ‘오류가 났다’인데, 1분 속도로는 이번 달 안에 들어가지만 14분 속도로는 이번 주 안에 터집니다. 연소율이 주는 것은 바로 이 ‘언제 터지나’의 답입니다.

실용적으로는 두 창을 같이 봅니다. 짧은 창은 최근 몇 시간이고 긴 창은 한 달입니다. 짧은 창에서 연소율이 높으면 지금 일어난 일이 큰 일입니다. 긴 창은 그것을 검증해서, 급한 신호가 실제로 예산을 갉아먹는지 확인합니다. 둘이 일치하면 사안입니다. 둘이 어긋나면, 둘 다 다시 보는 쪽이 안전합니다.

연소율이 주는 두 번째 가치는 판단의 속도입니다. ‘이 정도 오류는 보통 수준인데’라는 느낌은 매번 근거가 다르고, 기억에는 편파가 있습니다. 연소율은 언제나 같은 방식으로 같은 숫자를 냅니다. 오늘 7배, 어제 1.2배. 느낌이 흔들려도 숫자는 흔들리지 않습니다. 운영 판단의 많은 비용은 사실 이런 흔들림 사이에서 듭니다.

올리고 멈추는 산술

숫자를 고르고 경고를 세웠으면, 남은 것은 규율입니다. 언제 올리고 언제 멈출까요. 이 규율을 한 장의 문서로 쓰는 것을 에러 버짓 정책이라고 합니다. ‘에러 버짓을 잘 쓰세요’는 정책이 아닙니다. 바람입니다. 정책은 회의를 열지 않아도 결정이 되는 문장이어야 합니다.

형식은 이렇습니다. ‘이번 달 에러 버짓 사용이 절반을 넘으면, 버짓이 회복할 때까지 릴리스를 동결한다.’ 절반이라는 숫자는 검증된 상수가 아니라 [추정]의 영역입니다. 내 서비스가, 그리고 내가 감당할 위험의 크기를 정하는 자리이기 때문입니다. 중요한 것은 값이 아니라, ‘만약’을 숫자로 적어 두었다는 사실입니다.

숫자로 쓰이면 판단은 기분이 아닙니다. 월요일, 버짓은 80퍼센트 남았습니다. 올립니다. 목요일, 사건이 일어나서 버짓이 20퍼센트까지 줄었습니다. 동결합니다. 금요일, 기능이 전부 준비되어 있습니다. 그래도 20퍼센트라면 올리지 않습니다. 이것이 산술입니다. 버짓이 20퍼센트일 때 계속 올리면, 남은 한 달을 실패 하나에 거는 것이기 때문입니다.

동결이 주는 가치는 사고를 막는 것만으로 끝나지 않습니다. 동결은 ‘지금 올리지 않는’ 결정에 이름을 붙여 주는 장치입니다. 이름이 없으면 그 결정은 매번 용기가 되고 용기가 계속 필요하면 결국 어느 날 그냥 올리게 됩니다. 이름이 있으면 그 결정은 정책의 한 줄이 되고 실행할 때마다 새 용기가 필요 없습니다. 프로덕션 운영에서 비싼 것은 사고가 아니라, 이런 무이름 결정의 반복입니다.

예외는 같은 문서 안에 함께 써 두어야 합니다. 예외가 없는 정책은 힘으로 깨지게 됩니다. 보안 패치나 데이터 훼손 수정은 버짓이 동결되어 있어도 해야 할 일입니다. 예외가 정책에 적혀 있지 않으면, 나는 내 정책을 깨는 선택을 하게 됩니다. 한 번 깨진 정책은 다시 권위를 잃습니다. 그래서 예외를 정책 안에 편입합니다. ‘보안 패치와 데이터 훼손 수정은 동결과 무관하게 수행한다’는 한 줄이면 충분합니다.

동결은 영원이 아닙니다. 버짓은 시간이 지남에 따라 회복합니다. 사고가 없으면 1배 속도로, 즉 하루에 1분 남짓의 속도로 잔량이 돌아옵니다. 그래서 동결은 처벌이 아니라, 회복될 때까지의 대기입니다. 대기할 수 있는 구조여야, 이 정책은 장기적으로 지킬 수 있는 정책이 됩니다.

나 혼자인 위원회

1인 개발자에게 이 정책은 더 단순해야 합니다. 이유는 한 가지입니다. 정책을 강제할 위원회가 없기 때문입니다. 위원회가 있는 조직에서는 정책을 어긴 사람이 그 대가를 함께 지는 겁니다. 나 혼자인 곳에서는 대가를 짓누르는 쪽과 그 대가를 지는 쪽이 같은 사람입니다. 그래서 정책은 10초에 읽을 수 있을 만큼 짧게 써야 합니다.

내용은 각 한 줄씩이면 됩니다. 올림 임계값, 버짓이 이 이상 남아 있으면 자유롭게 올립니다. 동결 임계값, 버짓이 이 아래면 올림을 멈춥니다. 동결 시 행동, 동결되면 먼저 하는 일입니다. 롤백일 수도 있고 기능 플래그를 내릴 수도 있고 그냥 대기일 수도 있습니다. 이 세 줄보다 길면 아무도 읽지 않습니다. 아무도란 곧 나입니다.

정책 문서는 평소가 아니라 패닉 상태에서 꺼내 보기 위한 것입니다. 새벽 2시에 서비스가 죽고 판단력이 반쯤 꺼져 있을 때, 두 페이지의 원칙론은 도움이 안 됩니다. 세 줄은 도움이 됩니다. 세 줄은 평소의 내가 이미 동의한 문장이기 때문입니다. 패닉 상태에서 할 일은 새 결정을 내리는 것이 아니라, 평소의 나의 결정을 한 번 더 실행하는 것입니다.

연쇄를 정리하면, 에러 버짓은 안정성을 끝없는 목표에서 유한한 한계로 바꿉니다. 유한한 한계는 사용자의 경험을 재는 SLI로 정하고 43분이라는 체감 가능한 크기로 환산하며, 연소율이라는 속도로 읽습니다. 그리고 한 장의 정책 문장으로 고정되어, 올릴지 멈출지를 산술로 만듭니다.

안정성에 대한 밤의 고민은 결국 같은 문장으로 수렴합니다. ‘이 정도면 되나?’ 에러 버짓을 쓴 사람은 이 질문을 ‘버짓에 남는가?’로 바꿀 수 있습니다. 질문이 바뀌면 밤이 바뀌고 다음 아침에 올릴 수 있는 것의 목록이 달라집니다. 더 깊이 파고들고 싶다면, 이 주장을 장별로 더 정교하게 전개한 전자책 ‘오류 예산’이 함께 준비되어 있습니다.

참고 자료

본문의 SLO·SLI 정의, 연소율 기반 경고, 에러 버짓 정책의 형태는 아래 자료와 대조해 보실 수 있습니다. 본문의 동결 임계값은 검증된 상수가 아니라 저자의 운영 시작점입니다.

태그: burn-rate, error-budget, production-ops, reliability, sli, slo, solo-developer, sre

카테고리:

업데이트: