Skip to content
Published on

기술 부채 완전 가이드: 식별하고 측정하고 갚기

공유하기
Authors

들어가며

이 블로그에는 이미 기술 부채를 비즈니스 언어로가 있습니다. 그 글은 부채를 이해관계자에게 어떻게 설명하고 우선순위를 어떻게 협상하는지를 다룹니다. 즉 설득에 관한 글입니다.

이 글은 그 앞 단계입니다. 설득할 대상이 되려면 먼저 부채가 어디에 있는지 찾아내고, 거기에 숫자를 붙여야 합니다. 근거 없는 "코드가 더럽습니다"는 협상 테이블에서 이길 수 없습니다. 그래서 이 글의 주제는 식별과 측정, 그리고 목록을 유지하는 절차입니다.

한 문장으로 줄이면 이렇습니다. 부채의 존재를 주장하는 것과 부채의 이자를 보여 주는 것은 다른 일이고, 두 번째만 예산을 움직입니다.


1. 은유의 원래 뜻과 오용

1-1. Fowler의 사분면

Martin Fowler는 기술 부채를 두 축으로 나눕니다. 의도적이었는가 우발적이었는가, 그리고 무모했는가 신중했는가입니다.

                무모함(reckless)          신중함(prudent)
의도적    "설계할 시간이 없다"        "지금 출하하고 나중에 갚는다"
(deliberate)   대가를 모른 채 건너뜀      대가를 알고 선택함

우발적    "계층 분리가 뭔가요?"       "이제야 어떻게 했어야 하는지 알겠다"
(inadvertent)  더 나은 방법을 몰랐음      만들어 보고 나서야 알게 됨

Fowler는 우발적이면서 신중한 사분면을 특히 강조합니다. 프로젝트에서 1년쯤 프로그래밍을 해 봐야 최선의 설계 접근이 무엇이었는지 이해하게 되는 경우가 있다는 것입니다. 그리고 이 은유가 의도적인 두 사분면에만 유효한 것이 아니라 네 개 모두에 유효하다는 것이 그의 요지입니다.

1-2. 이 구분이 실무에서 하는 일

사분면은 분류 놀이가 아니라 처방이 달라지기 때문에 의미가 있습니다.

  • 의도적·신중: 상환 일정과 조건을 그 자리에서 함께 정합니다. 정하지 않으면 다음 분기에 우발적 부채처럼 보이게 됩니다.
  • 의도적·무모: 프로세스 문제입니다. 개인을 탓하는 대신 왜 그 선택이 가능했는지, 즉 마감과 리뷰 기준을 봅니다.
  • 우발적·무모: 학습과 리뷰의 문제입니다. 같은 실수가 반복되면 개인이 아니라 온보딩과 가이드가 부족한 것입니다.
  • 우발적·신중: 정상입니다. 이것을 부끄러워하면 팀은 배운 것을 코드에 반영하지 않게 됩니다.

1-3. 여기서 의견이 갈립니다

"기술 부채"라는 은유 자체가 유용한지에 대해 진짜 논쟁이 있습니다. 반대하는 쪽의 주장은 이 말이 형편없는 엔지니어링을 금융 용어로 세탁한다는 것입니다. 부채라는 말은 원래 의도적 선택과 상환 계획을 전제하는데, 실무에서는 아무 계획 없이 만들어진 나쁜 코드에도 같은 단어가 붙는다는 것입니다. 찬성하는 쪽은 이 은유가 비기술 이해관계자와 대화할 수 있는 거의 유일한 공통 언어라고 봅니다.

축은 세 가지입니다. 의도성이 실제로 있었는지, 상환 계획이 문서로 존재하는지, 그리고 이 단어가 상대방에게 어떤 행동을 유도하는지입니다. 계획 없이 쓰이면 반대 쪽 주장이 맞고, 계획과 함께 쓰이면 찬성 쪽 주장이 맞습니다.


2. 부채가 아닌 것들

목록을 만들기 전에 걸러 내야 합니다. 판별 기준은 하나입니다. 미래의 변경에 추가 비용을 물리는가. 물리지 않으면 부채가 아닙니다.

  • 취향 차이: 다른 스타일로 짜인 코드는 부채가 아닙니다. 스타일 논쟁을 부채 목록에 넣으면 목록 전체의 신뢰가 떨어집니다.
  • 오래되었지만 바뀌지 않는 코드: 3년째 아무도 손대지 않았고 정상 동작하는 모듈은 이자가 0입니다. 우선순위도 0입니다.
  • 아직 필요하지 않은 추상화의 부재: 일반화하지 않은 것은 부채가 아니라 판단입니다. 세 번째 사례가 나타나기 전의 중복은 대체로 정상입니다.
  • 버그: 결함이지 부채가 아닙니다. 결함은 고치는 것이고, 부채는 갚거나 갚지 않기로 결정하는 것입니다.
  • 미완성 기능: 백로그입니다.
  • 의도적으로 단순하게 유지한 설계: 확장성이 없는 것과 확장성을 포기하기로 결정한 것은 다릅니다.

반대로 흔히 부채로 인식되지 않지만 부채인 것들이 있습니다. 느린 CI, 손으로 하는 배포 전 점검, 로컬에서 재현되지 않는 환경, 신입이 첫 커밋까지 2주 걸리는 상태입니다. 이것들은 코드에 나타나지 않지만 모든 변경에 이자를 물립니다.


3. 부채의 유형학

유형을 나누는 이유는 발견 방법과 상환 방법이 유형마다 다르기 때문입니다.

유형이자가 나타나는 곳발견 방법
코드변경에 걸리는 시간, 리뷰 지적 반복핫스팟 분석, 리뷰 코멘트 집계
설계·아키텍처한 기능이 여러 모듈을 동시에 건드림변경 결합도, 함께 바뀌는 파일 쌍
테스트CI 시간, 불안정 실패, 배포 두려움실패율, 소요 시간, 커버리지 공백
의존성·보안업그레이드 불가, 스펙 위반 잔존취약점 스캔, 지원 종료일
데이터·스키마마이그레이션 위험, 되돌릴 수 없는 배포축소되지 않은 컬럼, 이중 쓰기 잔존
운영장애 빈도, 복구 시간, 수동 절차장애 회고, 런북의 수동 단계 수
지식·문서온보딩 기간, 같은 질문의 반복온보딩 소요일, 질문 로그

3-1. 외부 시계가 붙은 부채

대부분의 부채는 우리가 상환 시점을 정하지만, 일부는 외부가 시한을 정합니다. 이런 항목은 목록에서 따로 표시해야 합니다.

  • 보안 스펙의 변화: OAuth 2.0 보안 모범 사례인 RFC 9700은 리소스 소유자 비밀번호 자격 증명 그랜트에 대해 "사용되어서는 안 된다(MUST NOT be used)"고 못박고, 암묵적 그랜트에 대해서는 인가 응답에서의 액세스 토큰 주입이 방지되지 않는 한 "사용하지 않아야 한다(SHOULD NOT)"고 규정합니다. 이런 항목은 우리 일정이 아니라 감사와 심사 일정에 묶입니다.
  • 저장 위치 문제: OWASP 세션 관리 치트시트는 인증 토큰, 세션 ID, JWT, 리프레시 토큰을 localStoragesessionStorage에 저장하지 말라고 합니다. 이 API들은 같은 출처에서 실행되는 모든 자바스크립트가 접근할 수 있으므로 XSS 하나로 모든 토큰이 노출되기 때문입니다. 선택지 비교는 JWT와 세션, 무엇을 언제에 정리되어 있습니다.

3-2. 운영 부채는 장애로만 청구됩니다

Google SRE Book은 연쇄 장애를 "양의 되먹임의 결과로 시간이 지나며 커지는 장애"로 정의하고, 재시도는 항상 무작위화된 지수 백오프로 예약하라고 권합니다. 재시도 예산의 예시로는 프로세스당 분당 60회를 듭니다. 그리고 계층이 겹치면 재시도가 곱해져 세 계층이 각각 4회씩 재시도할 경우 사용자 동작 하나가 64번의 시도가 된다고 지적합니다.

백오프도 예산도 부하 차단도 없는 상태는 평소에는 아무 비용이 없습니다. 이자가 장애 순간에만 한꺼번에 청구되기 때문에 우선순위에서 계속 밀립니다. 이런 유형은 이자를 "발생 확률 × 장애 시 비용"으로 적어야 목록에서 살아남습니다.

3-3. 지식 부채

Design Docs at Google 글은 설계 문서가 다른 모든 문서와 마찬가지로 시간이 지나며 현실과 어긋나는 경향이 있다고 적습니다. 대응은 원본을 갱신하거나, 수정 사항을 덧붙이거나, 후속 문서를 연결하는 것입니다. 문서가 낡았다는 사실 자체보다 위험한 것은 낡았는지 여부를 아무도 모르는 상태입니다.


4. 어디에 있는지 찾기 — 변경 빈도와 복잡도

4-1. 나쁜 코드가 아니라 비싼 코드를 찾습니다

부채 탐색에서 가장 흔한 실수는 가장 지저분한 파일부터 찾는 것입니다. 지저분하지만 아무도 손대지 않는 파일의 이자는 0입니다. 찾아야 하는 것은 자주 바뀌면서 동시에 바꾸기 어려운 파일입니다.

# 예시 — 버전 관리 이력에서 변경 빈도 상위 파일 뽑기
# 최근 12개월, 파일별 커밋 수 상위 30개
git log --since='12 months ago' --name-only --pretty=format: \
  | grep -v '^$' | sort | uniq -c | sort -rn | head -30

# 이 목록을 복잡도 또는 줄 수와 곱해 핫스팟 점수를 만든다
# 점수 = 변경 횟수 x 복잡도 지표
# 상위 10개가 이번 분기에 볼 후보다

4-2. 계산할 때의 함정

  • 자동 생성 파일과 잠금 파일: 커밋 수가 압도적으로 많지만 사람이 읽지 않습니다. 먼저 제외합니다.
  • 대량 포매팅 커밋: 한 번의 스타일 적용이 모든 파일의 변경 횟수를 똑같이 올립니다. 해당 커밋을 제외합니다.
  • 파일 이름 변경: 이력이 끊겨 오래된 핫스팟이 새 파일처럼 보입니다.
  • 파일 크기 편향: 큰 파일은 그냥 자주 바뀝니다. 변경 횟수를 줄 수로 나눈 밀도도 함께 봅니다.

4-3. 코드 밖의 신호

핫스팟 분석은 코드 안만 봅니다. 다음 신호들은 목록에 넣을 후보를 코드 밖에서 알려 줍니다.

  • 같은 파일에서 반복해서 나는 장애: 회고 문서에서 파일 이름을 세어 봅니다.
  • 리뷰에서 반복되는 지적: 같은 지적이 세 번 나오면 그것은 개인 문제가 아니라 구조 문제입니다.
  • 온보딩에서 반복되는 질문: 지식 부채의 가장 정직한 지표입니다.
  • 배포 전 수동 절차의 수: 런북에서 사람이 손으로 하는 단계를 셉니다.
  • "그건 건드리면 안 돼요"라는 말: 이 문장이 나오는 모듈은 예외 없이 후보입니다.

4-4. 정적 분석 점수는 의미가 있는가 — 여기서 의견이 갈립니다

도구가 계산해 주는 부채 점수나 "상환에 필요한 시간" 추정치를 믿을 수 있는지에 대해 의견이 갈립니다. 유용하다는 쪽은 추세를 보는 데는 충분하며 논의의 출발점이 된다고 봅니다. 무의미하다는 쪽은 그 숫자가 규칙 위반 개수에 임의의 가중치를 곱한 것일 뿐이며, 정작 가장 비싼 부채인 설계 결합과 운영 부채는 전혀 보지 못한다고 봅니다.

축은 두 가지입니다. 점수를 절대값으로 쓰는지 추세로 쓰는지, 그리고 그 점수가 실제 변경 비용과 상관관계를 보이는지입니다. 우리 저장소에서 점수와 변경 리드 타임이 함께 움직이지 않는다면 그 점수는 우리에게 의미가 없습니다.


5. 이자를 계산하는 법

5-1. 원금이 아니라 이자가 핵심입니다

부채 항목에 "고치는 데 3주"라고만 적으면 그것은 원금입니다. 원금만으로는 우선순위를 정할 수 없습니다. 필요한 것은 갚지 않았을 때 매달 나가는 비용, 즉 이자입니다.

[이자 추정 — 관측 가능한 양으로만 적는다]
이자(월) = (이 부채 때문에 한 번의 변경에 추가로 드는 시간)
         x (그 영역의 월 변경 횟수)
         + (이 부채로 인한 월평균 장애 시간 x 장애 1시간의 비용)

예시
- 결제 모듈 이중 스키마: 변경당 +4시간, 월 6회 변경 → 월 24시간
- 불안정한 E2E 테스트: 재실행 대기 1.5시간 x 주 5회 → 월 30시간
- 수동 배포 점검: 배포당 40분 x 월 20회 → 월 13시간

원금(상환 견적)은 범위로 적는다. 예: 10~15 사람-일
회수 기간 = 원금 / 이자. 위 결제 모듈이면 약 4~6개월

5-2. DORA 지표를 이자의 대리 지표로 쓰기

팀 단위로 이자를 관측하는 가장 손쉬운 방법은 배포 지표입니다. DORA는 변경 리드 타임을 "변경이 버전 관리에 커밋된 시점부터 프로덕션에 배포되기까지 걸리는 시간"으로, 변경 실패율을 "배포 이후 즉각적인 개입이 필요했던 배포의 비율"로, 실패한 배포의 복구 시간을 "즉각적인 개입이 필요한 배포 실패로부터 복구하는 데 걸리는 시간"으로 정의합니다. 재작업률은 프로덕션 장애로 인해 발생한 계획되지 않은 배포의 비율입니다.

부채가 쌓이면 이 지표들이 먼저 움직입니다. 특히 변경 실패율과 복구 시간은 테스트 부채와 운영 부채에 직접 반응합니다.

5-3. "부채를 갚느라 느려진다"는 프레임이 틀린 이유

DORA는 연구 결과 속도와 안정성이 트레이드오프가 아니며 대부분의 팀에서 두 지표가 오히려 상관관계를 보인다고 보고합니다. DORA의 표현대로 장기적으로 실제 트레이드오프는 "더 나은 소프트웨어를 더 빠르게"와 "더 나쁜 소프트웨어를 더 느리게" 사이에 있습니다.

이 결과는 부채 논의에서 자주 쓰이는 "품질과 속도 중 하나를 고르라"는 프레임을 직접 반박합니다. 협상 자리에서 쓸 수 있는 가장 강한 근거이기도 합니다. 세부적인 설득 방법은 기술 부채를 비즈니스 언어로에 있습니다.

5-4. 측정할 때의 주의

  • 절대값보다 추세를 봅니다. 다른 팀, 다른 저장소와의 비교는 거의 언제나 잘못된 결론으로 갑니다.
  • 지표를 개인 평가에 쓰지 않습니다. 쓰는 순간 기록이 왜곡됩니다.
  • 이자 추정은 관측치로만 채웁니다. 근거 없는 추정치가 하나라도 섞이면 목록 전체의 신뢰가 무너집니다.
  • 회수 기간이 팀의 계획 지평보다 길면 그 항목은 지금 갚을 항목이 아닙니다.

6. 부채 목록을 만들고 유지하기

6-1. 목록이 없으면 부채는 감정 문제가 됩니다

목록의 목적은 기록이 아니라 비교입니다. 항목끼리 비교할 수 있어야 우선순위가 논쟁이 아니라 계산이 됩니다.

# 예시 — 부채 항목 한 개의 최소 필드
id: DEBT-114
title: 주문 테이블 통화 컬럼 이중 쓰기 잔존
type: data # code | design | test | dependency | data | ops | knowledge
location: services/order/**
quadrant: deliberate-prudent # Fowler 사분면
symptom: 주문 관련 변경마다 두 컬럼을 모두 고쳐야 함, 롤백 시 불일치 위험
interest: 변경당 +4시간, 월 6회 → 월 24시간 # 관측치
principal: 10-15 사람-# 견적, 범위로
payoff: 축소 단계 실행 (읽기 이전 완료 확인 후 옛 컬럼 제거)
risk_if_unpaid: 스키마 변경이 비가역이 되어 롤백 불가
external_clock: none # 있으면 날짜를 적는다
owner: order-team
review_by: 2026-11-01 # 재평가 시점

6-2. 유지 규칙

  • 항목 수에 상한을 둡니다. 200개짜리 목록은 목록이 아니라 창고입니다. 상한을 넘으면 이자가 낮은 항목부터 닫습니다.
  • 정기 재평가 시점을 필드로 넣습니다. 그 날짜에 이자를 다시 관측하지 못하면 항목을 닫습니다.
  • 관측치가 없는 항목은 후보로만 둡니다. "느낌상 문제"와 "월 24시간"은 같은 목록에 있으면 안 됩니다.
  • 닫힌 항목의 이력을 남깁니다. 갚지 않기로 한 이유가 다음 논의의 출발점이 됩니다.

6-3. 코드 주석은 목록이 아닙니다

코드 안의 TODOFIXME는 발견되기 쉽다는 장점이 있지만 우선순위도 소유자도 만료일도 없습니다. 실무 절충은 두 가지를 연결하는 것입니다. 주석에는 목록 항목의 식별자만 남기고, 이자와 계획은 목록에 둡니다. 이렇게 하면 코드를 읽다가 항목을 찾아갈 수 있고, 항목이 닫히면 주석도 함께 사라집니다.


7. 상환 계획을 로드맵에 넣는 방식들

[네 가지 편입 방식 — 전제와 실패 모드]

1. 고정 비율      매 스프린트 용량의 N%를 부채에 배정
   전제: 부채가 여러 영역에 분산되어 있다
   실패: 비율이 "남는 시간"으로 해석되면 언제나 0이 된다

2. 전용 기간      분기마다 1~2주를 부채에만 사용
   전제: 부채가 한 영역에 집중되어 있고 큰 덩어리다
   실패: 기간이 끝나면 원래 속도로 다시 쌓인다. 근본 원인은 그대로

3. 기능에 묶기    그 기능이 지나가는 경로의 부채만 함께 상환
   전제: 부채와 로드맵의 영역이 겹친다
   실패: 아무 기능도 지나가지 않는 영역의 부채는 영원히 남는다

4. 게이팅        특정 부채 상환을 새 기능의 선행 조건으로 지정
   전제: 그 부채가 다음 작업을 실제로 막고 있다
   실패: 남용하면 모든 기능이 인질이 되고 신뢰를 잃는다

7-1. 여기서 의견이 갈립니다

전용 부채 스프린트와 고정 비율 중 무엇이 나은지는 결론이 나 있지 않습니다. 전용 기간을 지지하는 쪽은 큰 구조 변경이 조각난 시간으로는 불가능하다고 봅니다. 고정 비율을 지지하는 쪽은 전용 기간이 부채를 "특별한 이벤트"로 만들어 평소에는 안 해도 되는 일로 인식시킨다고 봅니다.

축은 세 가지입니다. 부채가 집중되어 있는지 분산되어 있는지, 조직의 계획 주기가 얼마나 경직되어 있는지, 그리고 팀이 자율적으로 시간을 쓸 수 있는 신뢰가 있는지입니다. 실무에서는 분산된 부채에 고정 비율을, 집중된 큰 덩어리에 전용 기간을 쓰는 혼합이 자주 관찰됩니다. 이 조합 권고는 위 자료가 아니라 이 글에서 정리한 것입니다.

7-2. 상환도 배포 가능한 조각이어야 합니다

부채 상환은 대개 리팩터링의 형태를 띱니다. 그래서 리팩터링 완전 가이드의 규칙이 그대로 적용됩니다. 어느 시점에 멈춰도 배포 가능해야 하고, 인터페이스 변경은 확장·이행·축소로 나누고, 큰 상환은 되돌릴 수 있는 조각으로 자릅니다. 3주짜리 부채 상환 브랜치는 부채를 갚는 대신 새로운 부채를 만듭니다.

시스템 규모의 상환이 필요하다면 Strangler Fig 패턴 완벽 가이드가 그 구조를 다룹니다. 투자 판단 자체는 리팩터링의 경제학에 있습니다.


8. 갚지 않기로 결정하는 것도 결정이다

8-1. 갚지 않아도 되는 경우

  • 이자가 관측되지 않는 항목: 6개월 동안 그 영역의 변경이 0이었다면 이자는 0입니다.
  • 곧 폐기될 코드: 폐기 일정이 확정되어 있다면 상환은 낭비입니다. 다만 "곧"이 2년째 반복되고 있는지 확인해야 합니다.
  • 회수 기간이 계획 지평보다 긴 항목: 회수에 3년이 걸리는데 서비스 수명이 1년이면 갚지 않는 것이 옳습니다.
  • 상환 자체의 위험이 이자보다 큰 항목: 안전망이 없는 영역의 대규모 리팩터링이 여기 해당합니다.

8-2. 무시와 수용은 다릅니다

무시는 아무 기록이 없는 것이고, 수용은 누가, 언제, 어떤 근거로, 언제까지 갚지 않기로 했는지가 적혀 있는 것입니다. 수용된 항목은 목록에서 삭제하지 말고 상태만 바꿉니다. 재평가 날짜가 오면 이자를 다시 관측하고, 이자가 커졌으면 다시 열립니다.

8-3. 수용할 수 없는 것

외부 시계가 붙은 항목은 수용 대상이 아닙니다. 지원이 종료된 런타임, 규정에서 금지된 인증 방식, 이미 공개된 취약점은 우리 판단으로 미룰 수 있는 항목이 아닙니다. 3-1절에서 본 스펙 항목들이 여기 해당합니다. 이 구분을 목록의 필드로 만들어 두면 논의가 짧아집니다.


9. 다시 쌓이지 않게 하는 장치

9-1. 완료의 정의에 축소 단계를 넣습니다

기술 부채가 다시 쌓이는 가장 흔한 경로는 확장과 이행만 하고 축소를 하지 않는 것입니다. 인터페이스를 병렬로 늘려 놓고 옛 경로를 제거하지 않으면 그 순간부터 이자가 붙기 시작합니다. 완료의 정의에 "옛 경로 제거 티켓이 만들어졌고 만료일이 있다"를 넣는 것이 가장 값싼 방어입니다.

9-2. 리뷰를 기준선으로 씁니다

Google의 코드 리뷰 기준은 리뷰어가 변경이 완벽하지 않더라도 작업 대상 시스템의 전반적인 코드 건강을 확실히 개선하는 상태라면 승인하는 쪽을 택해야 한다고 정리합니다. 이 기준을 그대로 쓰면 리뷰가 부채 유입을 막는 관문이 됩니다. 같은 문서는 필수가 아닌 다듬기 제안에 "Nit: "을 붙이라고 권하고, 리뷰 요청에 응답하기까지 걸려도 되는 최대 시간을 영업일 하루로 정합니다.

리뷰 속도가 중요한 이유는 별도로 있습니다. 같은 자료는 느린 리뷰가 코드 정리와 리팩터링, 기존 변경에 대한 추가 개선을 위축시킨다고 적습니다. 즉 리뷰가 느린 조직에서는 부채 상환이 구조적으로 일어나지 않습니다.

9-3. 자동화로 잠그는 것들

- 린트 예외 목록: 항목 수가 늘면 빌드 실패. 줄어드는 것만 허용
- 폐기 경고: 날짜를 정해 경고를 오류로 승격하는 일정을 미리 커밋
- 의존성 갱신: 자동 PR을 켜고, 밀린 개수를 대시보드에 노출
- 플래그 만료: 만료일이 지난 기능 플래그는 CI에서 실패로 처리
- 커버리지 하한: 전체 수치가 아니라 '변경된 파일'의 커버리지에만 건다
- 수동 배포 단계: 런북의 수동 단계 수를 지표로 추적한다

9-4. 설계 문서로 앞단에서 막기

Design Docs at Google 글은 설계 문서를 코딩 전에 쓰는 비공식 문서로 정의하며, 높은 수준의 구현 전략과 핵심 설계 결정을 트레이드오프에 방점을 두고 담는다고 설명합니다. 그리고 해법이 자명하고 의미 있는 트레이드오프가 없다면 문서를 건너뛰라고 말합니다. 트레이드오프 분석 없이 사실상 구현 매뉴얼이 되어 버린 문서는 그냥 코딩을 시작하라는 신호라는 것입니다.

이 기준은 부채 예방에 그대로 쓸 수 있습니다. 되돌리기 어려운 결정에만 문서를 요구하면, 문서를 쓰는 비용을 들이는 지점과 나중에 가장 비싼 부채가 생기는 지점이 일치하게 됩니다.


퀴즈: 실력을 확인해 보세요

퀴즈 1: 팀이 "가장 복잡도가 높은 파일 10개"를 뽑아 상환 계획을 세웠습니다. 무엇이 빠졌을까요?

정답: 변경 빈도입니다. 복잡하지만 아무도 손대지 않는 파일의 이자는 0입니다.

설명: 부채의 우선순위는 원금이 아니라 이자로 정해집니다. 이자는 대략 "이 부채 때문에 한 번의 변경에 추가로 드는 시간"에 "그 영역의 변경 횟수"를 곱한 값입니다. 버전 관리 이력에서 최근 12개월 변경 횟수를 뽑아 복잡도와 곱한 핫스팟 점수를 쓰면 실제로 비싼 곳이 드러납니다. 자동 생성 파일과 대량 포매팅 커밋은 먼저 제외해야 합니다.

퀴즈 2: 부채 목록의 한 항목에 "코드가 지저분함, 고치는 데 3주"라고만 적혀 있습니다. 무엇을 요구해야 할까요?

정답: 관측된 이자와 갚지 않았을 때의 위험, 그리고 재평가 시점을 요구합니다.

설명: "3주"는 원금이고 원금만으로는 다른 항목과 비교할 수 없습니다. 증상은 관측 가능한 형태로 적어야 하며, 예를 들어 "변경당 추가 4시간, 월 6회 변경"이면 월 24시간이라는 비교 가능한 숫자가 나옵니다. 여기에 갚지 않았을 때의 위험과 재평가 날짜를 더하면 항목이 목록에서 살아 있을 자격을 갖춥니다.

퀴즈 3: 재시도에 백오프도 예산도 없는 서비스가 있습니다. 지난 6개월간 장애는 없었습니다. 이자를 어떻게 적어야 할까요?

정답: 발생 확률과 장애 1회의 비용을 곱한 기댓값으로 적습니다. 평소 이자가 0이라는 점을 항목에 명시합니다.

설명: 운영 부채는 평소에 비용이 나타나지 않고 장애 순간에 한꺼번에 청구되므로, 관측된 시간 비용만 쓰면 우선순위에서 계속 밀립니다. SRE Book은 재시도를 항상 무작위화된 지수 백오프로 예약하라고 권하고, 프로세스당 분당 60회 같은 재시도 예산을 예시로 듭니다. 또 세 계층이 각각 4회 재시도하면 사용자 동작 하나가 64번의 시도가 된다고 지적합니다. 이 증폭 계수를 이자 계산의 근거로 쓸 수 있습니다.

퀴즈 4: 경영진이 "이번 분기는 속도를 내야 하니 부채 상환을 미루자"고 합니다. 어떤 근거로 답할 수 있을까요?

정답: DORA의 연구 결과, 즉 속도와 안정성이 트레이드오프가 아니며 대부분의 팀에서 두 지표가 상관관계를 보인다는 결과를 제시합니다.

설명: DORA는 장기적으로 실제 트레이드오프가 "더 나은 소프트웨어를 더 빠르게"와 "더 나쁜 소프트웨어를 더 느리게" 사이에 있다고 정리합니다. 다만 이 근거는 일반론이므로, 우리 팀의 변경 리드 타임과 변경 실패율 추세를 함께 보여 주어야 설득력이 생깁니다. 특정 항목을 미루는 것 자체는 정당한 결정일 수 있으며, 그 경우 수용으로 기록하고 재평가 날짜를 정하면 됩니다.

퀴즈 5: 지원이 종료된 런타임 위에서 돌고 있는 서비스가 있습니다. 이 항목을 "수용"으로 처리해도 될까요?

정답: 안 됩니다. 외부 시계가 붙은 항목은 우리 판단으로 미룰 수 있는 대상이 아닙니다.

설명: 상환 시점을 우리가 정할 수 있는 항목과 외부가 시한을 정하는 항목은 성격이 다릅니다. 지원 종료된 런타임, 규정에서 금지된 인증 방식, 이미 공개된 취약점이 후자에 해당합니다. 예를 들어 OAuth 2.0 보안 모범 사례인 RFC 9700은 리소스 소유자 비밀번호 자격 증명 그랜트를 사용해서는 안 된다고 규정합니다. 목록에 외부 시계 필드를 두고 날짜를 적어 두면 이런 항목이 일반 항목과 섞이지 않습니다.


마치며

기술 부채에서 가장 어려운 일은 고치는 것이 아닙니다. 어디에 있는지 찾아내고, 거기에 비교 가능한 숫자를 붙이고, 그 숫자를 계속 갱신하는 일입니다. 이 작업이 되어 있으면 상환 결정은 대체로 쉽고, 되어 있지 않으면 어떤 설득 기법도 오래가지 않습니다.

절차를 한 줄로 압축하면 이렇습니다. 부채가 아닌 것을 걸러 내고, 자주 바뀌면서 바꾸기 어려운 곳을 찾고, 이자를 관측치로 적고, 목록으로 비교하고, 상환을 배포 가능한 조각으로 자르고, 갚지 않기로 한 것은 근거와 재평가 날짜와 함께 기록합니다. 그리고 축소 단계를 완료의 정의에 넣어 다시 쌓이지 않게 합니다.


참고 자료

  • Technical Debt Quadrant — Martin Fowler — 의도적/우발적과 무모함/신중함의 두 축, 네 사분면의 성격, 프로젝트에서 1년쯤 지나야 최선의 설계를 이해하게 된다는 서술, 그리고 은유가 네 사분면 모두에 유효하다는 요지를 인용했습니다. 2026-08-15 확인.
  • DORA metrics: the four keys — DORA — 변경 리드 타임, 변경 실패율, 실패한 배포의 복구 시간, 재작업률의 정의와 "속도와 안정성은 트레이드오프가 아니다"라는 결론을 인용했습니다. 2026-08-15 확인.
  • Addressing Cascading Failures — Google SRE Book — 연쇄 장애의 정의, 무작위화된 지수 백오프 권고, 분당 60회 재시도 예산 예시, 세 계층 4회 재시도가 64회가 되는 계산을 인용했습니다. 2026-08-15 확인.
  • Design Docs at Google — Industrial Empathy — 설계 문서의 정의와 트레이드오프 중심이라는 성격, 자명한 해법에는 문서를 건너뛰라는 조언, 그리고 문서가 시간이 지나며 현실과 어긋난다는 서술을 인용했습니다. 2026-08-15 확인.
  • Code Review Developer Guide — Google — 전반적인 코드 건강을 확실히 개선한다면 완벽하지 않아도 승인하라는 기준과 "Nit: " 관행을, 그리고 리뷰 속도 문서에서 느린 리뷰가 정리와 리팩터링을 위축시킨다는 서술과 영업일 하루 기준을 인용했습니다. 2026-08-15 확인.
  • RFC 9700 — OAuth 2.0 Security Best Current Practice — 리소스 소유자 비밀번호 자격 증명 그랜트를 사용해서는 안 된다는 규정과, 암묵적 그랜트에 대한 권고를 인용했습니다. 2026-08-15 확인.
  • OWASP Session Management Cheat Sheet — 인증 토큰과 세션 식별자를 브라우저 저장소에 두지 말라는 권고와 그 이유를 인용했습니다. 2026-08-15 확인.
  • 2절의 부채 판별 기준, 3절의 유형 표, 4절의 핫스팟 계산과 함정 목록, 5절의 이자 추정 식, 6절의 항목 템플릿과 유지 규칙, 7절의 네 가지 편입 방식, 8절의 수용 기준, 9절의 자동화 목록은 위 자료에 나오는 것이 아니라 이 글에서 정리한 절차입니다.

이어서 읽기

완전 가이드 시리즈