- 들어가며 — 83퍼센트 절감, 그리고 39.7센트
- 새 실험이 실제로 측정한 것 — 그리고 저자가 스스로 단 단서
- 오래된 증거는 생각보다 얇습니다
- 회수 기간 계산 — 변경 빈도가 곱셈 항입니다
- 이자 비유가 작동하는 곳과 무너지는 곳
- 매니저를 설득하는 법 — 미학이 아니라 이력으로
- 마치며 — 코드는 읽힐 때만 이자를 냅니다
- 참고 자료
들어가며 — 83퍼센트 절감, 그리고 39.7센트
2026년 7월 30일, martinfowler.com에 Thoughtworks의 Giles Edwards-Alexander가 쓴 The Economic Benefit of Refactoring이 올라왔습니다. 실험 설계가 깔끔합니다. AI 에이전트만으로 만든 15만 줄짜리 애플리케이션에서 문제가 되는 1만 7,155줄짜리 Rust 데이터 접근 모듈을 하나 고르고, "대표적인 변경"을 요청하는 프롬프트를 하나 고정한 뒤, 15단계에 걸쳐 리팩터링하면서 매 단계마다 같은 프롬프트를 다시 돌려 토큰 소비를 측정했습니다. 단계 사이에 변경 사항은 버려서 에이전트가 학습하지 못하게 했습니다.
결과는 인용하기 좋습니다. 입력 토큰이 159,564개에서 27,360개로, 132,204개(83퍼센트) 줄었습니다. 그리고 해커뉴스 토론에서 곧바로 나온 반박도 인용하기 좋습니다 — 그 절감액은 당시 가격으로 39.7센트입니다. 시간당 100달러짜리 시니어 개발자가 이 리팩터링을 지시하고 감독한 8시간과 비교하면 회수에 수천 번의 변경이 필요합니다.
두 숫자 모두 맞습니다. 그리고 이 대비가 리팩터링 논쟁이 20년째 결론에 도달하지 못하는 이유를 정확히 보여 줍니다 — 비용은 눈에 보이고 편익은 미래에 흩어져 있어서, 편익을 세는 방법에 따라 답이 뒤집힙니다. 이 글은 그 세는 방법을 다룹니다. 새 실험이 실제로 측정한 것, 기존 증거가 얼마나 얇은지, 회수 기간을 계산하는 식, 이자 비유가 무너지는 지점, 그리고 매니저 앞에서 미학 대신 쓸 숫자를 뽑는 명령어까지.
새 실험이 실제로 측정한 것 — 그리고 저자가 스스로 단 단서
먼저 이 실험이 측정한 대상을 정확히 해 둡시다. 사람의 이해 시간이 아니라 에이전트의 입력 토큰입니다. 즉 "이 변경을 하려면 얼마나 많은 코드를 읽어야 하는가"의 대리 지표입니다. 이 정의가 이 실험을 흥미롭게 만듭니다. 사람은 같은 파일을 두 번째 읽을 때 빨라지지만 에이전트는 매번 처음부터 읽으므로, 구조의 비용이 매 변경마다 정직하게 청구됩니다. 사람 대상 실험에서는 학습 효과 때문에 분리하기 어려운 신호가 여기서는 깨끗하게 보입니다.
숫자에서 읽을 것이 몇 가지 더 있습니다.
가장 큰 절감을 낸 것은 파일을 도메인에 맞춰 쪼갠 단계였습니다. 15단계 중 마지막 단계 하나가 입력 토큰을 107,205개에서 27,360개로 떨어뜨렸습니다. 저자는 여기서 중요한 단서를 답니다 — 파일을 아무렇게나 잘게 나누는 것은 별로 도움이 안 되며, 에이전트가 여러 파일을 뒤져야 하기 때문입니다. 앞선 단계들(중복 추출 같은 국소 정리)이 마지막 분할을 가능하게 한 준비 작업이었다는 것입니다. 즉 효과는 마지막 단계에 몰려서 나타나지만 그 단계만 따로 할 수는 없습니다.
출력 토큰은 거의 변하지 않았습니다(약 1,700~2,460개). 리팩터링이 "읽는 비용"은 줄였지만 "쓰는 비용"에는 영향이 없었다는 뜻이고, 저자도 이 부분은 결론을 내리지 않습니다.
그리고 총 코드량은 줄지 않았습니다. 가장 큰 파일이 17,155줄에서 9,269줄로 내려갔지만, 데이터 접근 계층 전체는 19개 파일에 걸쳐 약 16,500줄로 거의 그대로입니다. 해커뉴스에서 이 점을 지적한 댓글이 있었는데, 리팩터링이 보통 코드량을 줄인다는 통념과 어긋난다는 것입니다.
저자 자신이 붙인 단서가 꽤 길고, 그대로 옮길 가치가 있습니다.
- 토큰 계수 방식이 근사치입니다. 문자 수를 4로 나누는 방식을 썼고, 저자는 실시간으로 토큰을 정확히 세는 신뢰할 만한 방법이 없었다고 적습니다. 해커뉴스에서 "제대로 된 토크나이저 라이브러리가 있는데 왜"라는 반박이 나왔습니다.
- 그린필드 앱 하나, 개발자 한 명, 모듈 하나, 변경 유형 하나에 대한 단일 실험입니다.
- 리팩터링 계획을 세우고 실행하는 데 든 토큰은 세지 않았습니다. 상한을 500만 토큰으로 추정하지만 검증된 값이 아닙니다.
- 그리고 가장 흥미로운 단서 — 에이전트는 리팩터링을 잘하지 못했습니다. 어떤 리팩터링이 적절한지 스스로 판단하지 못해 단계마다 사람이 명시적으로 지시해야 했고, 실제 변환 작업은 grep과 sed를 쓰는 파이썬 스크립트로 이뤄졌는데 들여쓰기에서 자주 혼동을 일으켰습니다. 가장 가치 있었던 리팩터링은 처음에 놓쳐서 나중에 다시 적용해야 했습니다.
요컨대 이 글은 "리팩터링이 돈이 된다"의 증명이 아니라, 에이전트 기반 개발에서 구조 비용을 측정할 방법 하나를 제안한 첫 시도입니다. 저자도 "하나의 실험일 뿐이지만 흥미로운 첫걸음"이라고 썼습니다. 그렇게 읽는 것이 맞습니다.
오래된 증거는 생각보다 얇습니다
리팩터링이 이득이라는 주장에는 40년치 직관과 놀랄 만큼 적은 정량 근거가 붙어 있습니다. 실제로 인용할 만한 것을 나열하면 목록이 짧습니다.
가장 자주 인용되는 것은 Adam Tornhill과 Markus Borg의 Code Red: The Business Impact of Code Quality(2022)입니다. 39개의 상용 프로덕션 코드베이스, 30,737개 파일을 대상으로 소스 분석과 버전 관리 이력, Jira 이슈를 결합해 세 가지를 보고했습니다 — 품질이 낮은 코드에 결함이 15배 많고, 이슈 해결에 평균 124퍼센트 더 오래 걸리며, 최대 사이클 타임이 9배까지 벌어집니다.
이 연구는 진지하지만 한계도 분명합니다. 코드 품질 측정에 저자들이 만든 상용 도구의 지표를 썼고, 관계는 상관이지 인과가 아닙니다. 애초에 어려운 문제 영역이 지저분한 코드와 긴 해결 시간을 동시에 만들어 냈을 가능성이 배제되지 않습니다. 그리고 결정적으로, 이 연구는 품질이 낮은 코드의 비용을 측정한 것이지 리팩터링의 수익을 측정한 것이 아닙니다. 둘은 다릅니다. 리팩터링에는 비용과 회귀 위험이 따로 있습니다.
Martin Fowler 본인의 입장도 인용할 가치가 있습니다. Is High Quality Software Worth the Cost?(2019, 2024년에 Tornhill과 Borg 연구를 인용해 갱신)에서 그는 설계 지구력 가설을 제시하면서 동시에 이렇게 인정합니다 — 소프트웨어 팀이 전달한 기능을 측정할 방법이 없으므로 그 결과에 확실한 숫자를 붙이는 것은 불가능하다는 것입니다. 그가 제시한 그래프는 예시이지 데이터가 아닙니다. 이 분야에서 가장 영향력 있는 주장의 저자가 근거의 성격을 이렇게 명확히 밝혀 둔 것은 오히려 신뢰할 만한 태도입니다. 그가 덧붙이는 실무적 관찰 하나는 유용합니다 — 숙련 개발자들은 나쁜 코드가 자신을 눈에 띄게 느리게 만드는 것을 몇 주 안에 체감하며, 따라서 품질과 비용을 맞바꿀 구간 자체가 그리 길지 않다는 것입니다.
반대 방향 증거도 실재합니다. 리팩터링과 버그의 관계를 다룬 차등 재현 연구(ESEC/FSE 2020)는 특정 리팩터링 유형, 특히 상속 계층을 건드리는 작업이 새 결함 도입과 자주 연관된다고 보고합니다. MSR 2022의 Is refactoring always a good egg?는 리팩터링이 코드 스멜을 제거하거나 아무 영향을 주지 않는 경우가 대부분이며 이는 선행 연구와 어긋난다고 적습니다. 더 최근 연구들은 방법론 문제를 지적합니다 — 리팩터링과 버그 수정, 버그 유입이 같은 커밋 안에 뒤엉켜 있어서 효과를 분리하는 것 자체가 어렵다는 것입니다.
정직한 요약은 이렇습니다. 낮은 품질이 비싸다는 증거는 있고, 리팩터링이 그 비용을 회수한다는 일반적 증거는 얇으며, 어떤 종류의 리팩터링은 위험을 늘립니다. 그러니 "리팩터링은 좋은 것"이라는 전제로 논의를 시작하면 안 되고, 케이스별 계산이 필요합니다.
회수 기간 계산 — 변경 빈도가 곱셈 항입니다
증거가 얇을 때 쓸 수 있는 방법은 일반 명제 대신 특정 모듈에 대한 계산입니다. 필요한 항은 다섯 개뿐입니다.
연간 절감액은 두 갈래로 나옵니다. 하나는 변경 비용 절감이고, 다른 하나는 결함 비용 절감입니다.
연간 절감 = (C × T × S × H) + (D × F × K)
C : 이 모듈을 건드리는 연간 변경 횟수 (git 이력에서 뽑음)
T : 변경 한 건당 평균 소요 시간 (이슈 트래커에서 뽑음)
S : 그중 구조 때문에 낭비되는 비율 (추정. 0.2~0.5가 보수적)
H : 시간당 인건비
D : 이 모듈에서 유래한 연간 결함 수
F : 결함 한 건당 총비용 (대응 + 재작업 + 고객 영향)
K : 리팩터링으로 줄어들 것으로 보는 결함 비율 (추정. 0.3이면 낙관적)
리팩터 비용 = (R × H) + (P × F_reg)
R : 리팩터링 작업 시간 (테스트 보강 포함)
P : 회귀를 낼 확률 × 예상 건수
F_reg : 회귀 한 건의 비용
회수 기간(개월) = 리팩터 비용 / (연간 절감 / 12)
여기서 구조적으로 중요한 것은 C가 곱셈 항이라는 사실입니다. C가 0이면 T, S, H가 아무리 커도 절감은 0입니다. 이것이 "바뀌지 않는 코드는 정리할 가치가 없다"의 수학적 표현입니다. 5년 전에 짜서 아무도 손대지 않고 잘 돌아가는 지저분한 모듈은 회수되지 않습니다. 미학적으로 거슬리는 것과 경제적으로 손해인 것은 다른 문제이고, 이 식은 그 둘을 분리해 줍니다.
세 모듈을 놓고 계산해 보면 차이가 극명합니다. 시간당 인건비 10만 원, 결함 한 건 200만 원, S는 0.3, K는 0.3으로 잡은 예시입니다. 리팩터 비용은 인건비 항만 넣었고 회귀 위험 항은 뺐으니, 실제로는 아래 회수 기간보다 길어집니다.
| 모듈 | 연간 변경 C | 건당 시간 T | 연간 결함 D | 연간 절감 | 리팩터 비용 | 회수 기간 |
|---|---|---|---|---|---|---|
| 주문 처리 (핫스팟) | 84회 | 6시간 | 11건 | 약 2,172만 원 | 160시간 = 1,600만 원 | 약 9개월 |
| 리포트 생성기 | 12회 | 8시간 | 2건 | 약 408만 원 | 120시간 = 1,200만 원 | 약 35개월 |
| 레거시 정산 배치 | 1회 | 20시간 | 0건 | 약 60만 원 | 200시간 = 2,000만 원 | 약 33년 |
세 번째 줄이 이 표의 요점입니다. 레거시 정산 배치는 아마 코드베이스에서 가장 읽기 괴로운 파일일 것이고, 팀에서 가장 자주 언급되는 부채일 것입니다. 그리고 손대면 안 되는 코드입니다. 회수 기간이 서비스 수명보다 깁니다.
숫자를 만들 때 주의할 점 셋. S는 정직하게 낮게 잡으세요. Code Red의 124퍼센트를 그대로 S로 환산하면 0.55가 나오지만, 그건 상관 데이터에서 나온 상한이지 당신 모듈의 값이 아닙니다. P를 0으로 두지 마세요. 앞서 본 반대 방향 연구들이 말하는 게 이 항입니다. 특히 상속 계층을 건드리는 리팩터링에는 위험 프리미엄을 붙이세요. 그리고 계산 결과가 "하지 말 것"으로 나오면 그 결론을 받아들이세요. 이 계산의 가치는 승인을 얻는 데 있는 게 아니라 어디에 쓰지 않을지를 정하는 데 있습니다.
이자 비유가 작동하는 곳과 무너지는 곳
기술 부채라는 말은 1992년 Ward Cunningham이 만들었고, 지금은 이 논의의 기본 언어가 됐습니다. 이 비유는 실제로 두 가지 일을 잘합니다 — 지금 빨리 가는 대가로 나중에 더 낸다는 구조를 재무 언어로 번역해 주고, 그래서 엔지니어링 밖의 사람에게 논증이 통하게 만들어 줍니다. 그것만으로도 충분히 유용합니다.
다만 세 지점에서 무너집니다.
첫째, 이자가 시간이 아니라 접촉에 붙습니다. 금융 부채는 가만히 있어도 이자가 쌓이지만, 기술 부채는 그 코드를 건드릴 때만 청구됩니다. Cunningham 자신의 표현도 "제대로 되지 않은 코드에 쓰는 모든 시간이 그 부채의 이자"입니다 — 시간이 흐르는 것이 아니라 시간을 쓰는 것이 조건입니다. 앞 절의 C가 곱셈 항인 이유가 이것이고, 이 차이 하나 때문에 "부채는 빨리 갚을수록 좋다"는 금융적 직관이 코드에서는 틀립니다.
둘째, 원금을 계산할 수 없습니다. 이율도, 상환 일정도, 만기도 없습니다. 부채 총액을 금액으로 환산해 대시보드에 띄우는 도구들이 있지만, 그 숫자의 분모가 무엇인지 설명할 수 있는 사람은 드뭅니다. 비유를 모델로 착각하는 순간 이 지표는 관리 대상이 되고, 관리 대상이 된 지표는 최적화되기 시작합니다.
셋째, 선형이 아닙니다. 결합도가 높은 지점의 부채는 국소적인 부채보다 훨씬 비쌉니다. 같은 100줄의 지저분한 코드라도 20개 모듈이 의존하는 자리에 있으면 비용이 다릅니다. 금융 비유에는 이 위치 개념이 없습니다.
그리고 Cunningham 본인이 여러 번 정정한 오해가 하나 있습니다 — 그가 말한 부채는 나중에 제대로 하겠다며 일부러 대충 짜는 것이 아닙니다. 빨리 출시해서 도메인에 대한 이해를 얻고, 그 이해를 코드에 반영하기 위해 리팩터링하는 순환을 뜻했습니다. 즉 원래 비유에서 부채는 "나쁜 코드"가 아니라 아직 반영되지 않은 학습이었습니다. 이 정의가 실무적으로 더 유용한 이유는, 무엇을 정리해야 하는지를 알려 주기 때문입니다 — 지금 우리가 도메인에 대해 아는 것과 코드가 가정하는 것이 어긋난 자리입니다.
매니저를 설득하는 법 — 미학이 아니라 이력으로
"이 코드는 지저분합니다"는 설득력이 없습니다. 듣는 쪽에서 검증할 방법이 없고, 취향 문제로 접수되기 때문입니다. 대신 앞 절의 계산식에 넣을 값들을 실제 데이터에서 뽑아 오세요. 전부 감사 가능한 숫자입니다.
# 1) 변경 빈도 C: 지난 12개월 파일별 커밋 수 상위 20
git log --since="12 months ago" --name-only --pretty=format: \
| sed '/^$/d' | sort | uniq -c | sort -rn | head -20
# 2) 결함 관련 변경 D: 버그 수정 커밋만 걸러 같은 집계
# (커밋 규약이 있다면 --grep, 없다면 이슈 키 패턴으로)
git log --since="12 months ago" --name-only --pretty=format: \
--grep='^fix' --grep='hotfix' --grep='BUG-' \
| sed '/^$/d' | sort | uniq -c | sort -rn | head -20
# 3) 핫스팟: 변경 빈도가 높은 파일 중 큰 것만 남긴다
git log --since="12 months ago" --name-only --pretty=format: \
| sed '/^$/d' | sort | uniq -c | sort -rn \
| awk '{ n=$1; f=$2; cmd="wc -l < " f; cmd | getline loc; close(cmd);
if (loc > 500 && n > 20) printf "%5d changes %6d loc %s\n", n, loc, f }'
이 출력을 그대로 들고 가면 대화가 달라집니다. "주문 처리 모듈은 지난 12개월 동안 84번 수정됐고, 그중 23번이 버그 수정이었으며, P2 인시던트의 31퍼센트가 이 파일을 지나갑니다"는 검증 가능한 진술입니다. 여기에 회수 기간 하나를 붙이면 승인 요청이 아니라 투자 제안이 됩니다.
그다음에 붙일 것이 범위가 정해진 실험입니다. 전면 정리를 요구하지 말고, 핫스팟 하나에 정해진 시간을 배정하고 리드 타임의 전후를 재겠다고 제안하세요. 실패하면 그 범위에서 끝나고, 성공하면 다음 회차의 근거가 생깁니다. 앞서 본 새 실험이 실무에 주는 시사도 여기입니다 — 같은 변경 요청을 리팩터링 전후로 한 번씩 돌려 보는 것이 가장 값싼 측정 방법입니다. 에이전트를 쓰고 있다면 토큰 수가, 사람만 쓰고 있다면 첫 커밋까지의 시간이 대리 지표가 됩니다.
마지막으로, 논쟁에서 이기려 하지 마세요. 세 모듈을 계산해 두 개는 "안 함"으로 결론 내고 하나만 제안하는 사람이, 전부 정리해야 한다고 주장하는 사람보다 훨씬 빨리 승인을 받습니다.
마치며 — 코드는 읽힐 때만 이자를 냅니다
정리하면 이렇습니다.
- 새로 나온 실험은 리팩터링 15단계로 같은 변경의 입력 토큰을 83퍼센트 줄였지만, 금액으로는 변경당 39.7센트이고 저자 스스로 단일 그린필드 실험이라고 못 박습니다. 결론이 아니라 측정 방법의 제안으로 읽는 것이 맞습니다.
- 기존 증거는 얇습니다. 낮은 품질이 비싸다는 상관 근거는 있지만(결함 15배, 해결 시간 124퍼센트), 리팩터링이 그 비용을 회수한다는 일반 근거는 없고 일부 리팩터링 유형은 결함 유입과 연관됩니다.
- 그래서 일반 명제 대신 모듈별로 계산하세요. 변경 빈도가 곱셈 항이므로, 바뀌지 않는 코드는 아무리 지저분해도 회수되지 않습니다.
- 이자 비유는 매니저에게 통하지만 모델이 아닙니다. 이자는 시간이 아니라 접촉에 붙고, 원금은 계산되지 않으며, 결합도에 따라 비선형입니다.
- 설득은 미학이 아니라 git 이력으로 하세요. 세 후보 중 둘을 스스로 탈락시키는 제안이 가장 빨리 통과합니다.
한 줄로 줄이면, 리팩터링의 가치는 코드의 상태가 아니라 그 코드를 앞으로 몇 번 읽을 것인지에 달려 있습니다.
참고 자료
- Giles Edwards-Alexander — The Economic Benefit of Refactoring (martinfowler.com, 2026-07-30)
- Hacker News — The Economic Benefit of Refactoring 토론(방법론 비판 포함)
- Tornhill & Borg — Code Red: The Business Impact of Code Quality (arXiv:2203.04374)
- Martin Fowler — Is High Quality Software Worth the Cost? (2019, 2024 갱신)
- On the relationship between refactoring actions and bugs: a differentiated replication (ESEC/FSE 2020)
- Is refactoring always a good egg? (MSR 2022)
- Agile Alliance — Introduction to the Technical Debt Concept (Cunningham 비유의 원래 의미)
- AI로 코드베이스를 옮기는 실전 절차 — 측정 지표 편 (관련 글)
현재 단락 (1/78)
2026년 7월 30일, martinfowler.com에 Thoughtworks의 Giles Edwards-Alexander가 쓴 [The Economic Benefit of Re...