2026 All-Day-Project (136/365)
4장. 삽으로 팔 것인가, 포크레인을 빌릴 것인가 (이 글)
5장: 가장 싸게 틀려라
6장: 수확은 해석이다
한 농부가 있습니다. 밭을 크게 넓히려고 포크레인 기사를 불렀습니다.
기사는 장비와 함께 도착했고, 바로 작업을 시작하려 합니다.
농부가 그를 잠깐 멈춥니다.
"이쪽은 괜찮은데, 저쪽 구석은 손으로 해주세요. 예전에 배수 파이프를 묻어뒀거든요. 포크레인이 긁으면 터집니다. 그리고 저 나무 뿌리 주변은 2미터 이상 건드리면 안 돼요. 지난해 접목한 거라 아직 약해요. 여기서부터 여기까지는 한 번에 파도 되고, 이 라인은 두 번에 나눠서 파주세요."
농부는 포크레인을 운전할 줄 모릅니다. 유압 실린더가 몇 톤인지도 모르고, 버킷의 용량이 몇 세제곱미터인지도 모릅니다. 그런데 이 몇 분의 대화가 없었다면, 기사는 당연히 가장 효율적인 경로로 밭 전체를 한 번에 파냈을 것입니다. 그리고 배수 파이프가 터졌을 것입니다. 나무가 죽었을 것입니다. 밭 전체의 운명이 달라졌을 것입니다.
농부가 한 일은 기술을 결정한 것이 아닙니다. 기술 결정에 필요한 맥락을 제공한 것입니다. 여기 뭐가 묻혀 있는지, 뭐가 약한지, 어디까지가 허용되고 어디부터는 건드리면 안 되는지. 이 맥락이 없으면 아무리 유능한 기사라도 바르게 팔 수 없습니다.
PM이 엔지니어링팀과 맺는 관계도 이와 같습니다.
그런데 PM들이 이 관계를 두 가지 방식으로 망가뜨립니다. 엔지니어가 "이거 O(n²)이라 터져요"라고 말할 때, PM은 대개 둘 중 하나로 반응합니다.
하나는 "알아서 해." — "기술은 너희 영역이니까, 너희가 판단해. 나는 제품만 볼게." 존중처럼 들리지만 실은 포기입니다. 이 말이 떨어지는 순간, 기술 결정은 제품과 분리됩니다. 엔지니어는 기술적으로 가장 깔끔한 선택을 할 수밖에 없고, 그 선택이 제품 전략과 어긋나도 아무도 이야기하지 않습니다.
다른 하나는 "그래도 해." — "일정이 급하니까, 어떻게든 해봐." 이 말이 떨어지는 순간, 엔지니어는 배수 파이프 위로 포크레인을 몰게 됩니다. 뭐가 묻혀 있는지는 아무도 말해주지 않은 채로.
두 반응 모두 공통점이 있습니다. PM이 기술 대화에 참여하지 않는다는 것. 이 장은 그 대화에 참여하는 법에 대한 이야기입니다. PM이 코드를 짤 필요는 없습니다. O(n²)을 해결할 필요도 없습니다. 다만 이 대화는 할 줄 알아야 합니다.
엔지니어가 기술적 우려를 꺼낼 때, PM이 던져야 할 질문은 사실 많지 않습니다.
다섯 개면 충분합니다. 이 다섯 개가 기술적 제약을 제품의 언어로 번역합니다.
"지금 문제인가요, 나중 문제인가요?" — 시급성을 가르고 우선순위를 정합니다.
"되돌릴 수 있는 결정인가요, 없는 결정인가요?" — 의사결정의 무게를 정합니다.
"이 비용은 어디서 발생하나요?" — 성능 병목의 위치를 사용자 경험 지도 위에 올립니다.
"이것 없이 핵심 가치를 전달할 수 있나요?" — 기술적 완성도와 최소 가치 전달의 경계를 긋습니다.
"이 부채를 언제, 어떻게 갚나요?" — 의도적 부채에 상환 계획을 붙입니다.
이 다섯 질문이 왜 중요한지를 하나씩 풀어보겠습니다. 그리고 각 질문 뒤에 숨어 있는 프레임과 사례까지.
Jeff Bezos는 2016년 아마존 주주 서한에 이렇게 썼습니다.
"어떤 결정은 중대하고 되돌릴 수 없거나 거의 되돌릴 수 없다 — 일방통행 문이다.
이런 결정은 신중하게, 천천히, 충분한 숙의와 협의를 거쳐 내려져야 한다.
하지만 대부분의 결정은 그렇지 않다. 그것들은 변경 가능하고 되돌릴 수 있는 — 양방향 문이다."
Bezos의 경고는 이것이었습니다. 조직이 커지면 대부분의 결정(양방향 문 포함)에 일방통행 문의 무거운 프로세스를 적용하는 경향이 생긴다고. 결과는 느려짐, 방어적 리스크 회피, 불충분한 실험, 그리고 발명의 감소.
기술 결정도 똑같이 두 종류로 나뉩니다.
일방통행 문에 가까운 결정들: 데이터베이스 스키마 변경, 도메인 모델의 근본 설계, 결제 시스템 통합, 공개 API의 인터페이스 계약, 회원 식별자 체계. 한번 정해서 수개월~수년 동안 수많은 코드와 데이터가 그 위에 쌓이면, 되돌리는 비용이 처음 만드는 비용의 10배, 100배가 됩니다.
양방향 문에 가까운 결정들: UI 컴포넌트의 레이아웃, 내부 API의 응답 포맷, 기능 플래그 뒤에 있는 A/B 테스트, 특정 알고리즘의 구현 방식, 캐시 전략. 필요하면 다음 스프린트에 바꿀 수 있습니다.
PM이 엔지니어에게 물어야 할 한 가지는 이것입니다.
"이 결정, 6개월 뒤에 틀렸다고 판명되면 되돌리는 데 얼마나 걸려요?"
대답이 "한 스프린트면 돼요"면 양방향 문입니다. 빨리 결정하고, 빨리 실행하고, 틀렸으면 빨리 바꿉니다. 대답이 "최소 3개월, 게다가 기존 사용자 데이터 마이그레이션이 필요해요"면 일방통행 문입니다. 신중하게, 충분히, 여러 사람의 눈으로 봅니다.
가장 흔한 실수는 두 가지입니다. 양방향 문에 과도한 시간을 쓰는 것(결정이 느려지고 실험이 죽는다)과 일방통행 문을 양방향 문처럼 가볍게 여기는 것(되돌리려니 너무 늦었다). 이 구분만 제대로 해도 PM의 속도와 안전성은 동시에 올라갑니다.
"기술 부채"라는 말은 이제 모든 개발 회의실에서 쓰이는 말이지만, 이 용어가 처음 등장한 맥락을 아는 사람은 의외로 적습니다.
1992년 OOPSLA 컨퍼런스. Ward Cunningham은 Wyatt Software에서 포트폴리오 관리 시스템을 개발하고 있었습니다. 기술을 모르는 상사에게 "왜 리팩토링이 필요한가"를 설명해야 했는데, 상사는 금융을 알았습니다. Cunningham은 그래서 금융 용어를 빌려옵니다.
"처음 짜는 코드를 출시하는 건 부채를 지는 것과 같다. 약간의 부채는 빠르게 갚기만 하면 개발 속도를 높여준다... 위험한 건 부채를 갚지 않을 때다.
'완전히 맞지는 않은' 코드에 쓰는 1분 1초가 그 부채의 이자다."
이 문장의 핵심은 자주 오해되는 지점에 있습니다. Cunningham은 부채가 나쁘다고 말하지 않았습니다. 그는 오히려 반대로 말했습니다. 약간의 부채는 개발 속도를 높여준다고. 중요한 건 "빠르게 갚기만 하면"입니다. 부채 자체가 문제가 아니라, 갚지 않는 것이 문제입니다.
Martin Fowler는 이 개념을 한 단계 더 밀어 사분면으로 정리했습니다. 가로축은 의도(Deliberate / Inadvertent) — 부채를 의도적으로 졌는가, 모르고 졌는가. 세로축은 신중함(Prudent / Reckless) — 신중한 판단이었는가, 무모했는가.
이 네 칸 중 건강한 부채는 오직 하나, 오른쪽 위의 Deliberate + Prudent입니다. "우리는 지금 부채를 지고 있다는 걸 안다. 그리고 조기 출시의 이득이 나중 상환 비용보다 크다고 판단했다." 이게 성숙한 엔지니어링 판단이고, PM이 엔지니어와 함께 내려야 하는 결정입니다.
왼쪽 위(Deliberate + Reckless)는 가장 위험합니다. "좋은 설계가 뭔지 알지만 시간이 없으니 그냥 해." 이 선택은 단기적으로 출시를 지키지만, 중기적으로 거의 항상 조직을 무너뜨립니다. 오른쪽 아래(Inadvertent + Prudent)는 "이제야 알겠다"로 요약되는, 어떤 뛰어난 팀도 1년 후에 겪게 되는 깨달음입니다.
모르는 게 죄는 아니지만, 깨달은 순간부터는 갚아야 합니다. 왼쪽 아래(Inadvertent + Reckless)는 부채인 줄도 모르는 상태 — 가장 조용하게 쌓이다가, 가장 크게 터집니다.
PM이 관여해야 하는 건 주로 Deliberate 축입니다. "이 부채를 의도적으로 지겠다"는 결정은 엔지니어 혼자 할 수 없습니다. 그 부채의 이득(시장 속도, 학습 기회)과 비용(상환 일정, 확장 한계)을 함께 평가해야 하기 때문입니다. 그리고 결정했으면, 로드맵에 상환 일정을 넣어야 합니다. 상환 일정 없는 의도적 부채는 그냥 무모한 부채입니다.
이 차이가 얼마나 큰지는 두 회사의 이야기를 비교해보면 선명해집니다.
트위터는 2006년에 Ruby on Rails로 시작했습니다. 당시로서는 가장 빠른 출시 방법이었고, 초기 성장을 뒷받침했습니다. 그런데 곧 한계가 옵니다. 피크 트래픽마다 서버가 다운됐고, "Fail Whale"이라는 에러 페이지의 고래 그림이 트위터의 비공식 마스코트가 됐습니다.
트위터는 이걸 부채로 인식했습니다. 의도적이었고, 신중했던 부채입니다. 초기에 Rails를 선택한 건 빠른 출시를 위해 확장성을 잠시 저당 잡은 것이었고, 2009년부터 Java/Scala로 단계적으로 전환하면서 갚기 시작했습니다. 2011년 Java 서버 "Blender"가 가동됐고, 호스트당 초당 200–300 요청을 처리하던 시스템이 초당 10,000–20,000 요청을 처리하게 됐습니다. 예상의 10배 이상이었습니다.
트위터의 부채는 성장을 가능하게 한 도구였고, 제때 갚혔기 때문에 회사를 무너뜨리지 않았습니다.
Cunningham의 원래 정의가 작동한 모범 사례입니다.
Knight Capital은 반대편에 있습니다. 2012년 8월 1일, 이 회사는 소프트웨어 배포 사고로 45분 만에 4억 4천만 달러를 잃고 사실상 파산했습니다.
사건의 원인은 단순했습니다. 새로운 Retail Liquidity Program 코드를 8대 서버에 배포하는데, 1대에 복사하지 않았습니다. 그 한 대의 서버에는 수년 전에 폐기된(deprecated) Power Peg 코드가 여전히 남아 있었고, 새 코드의 플래그가 옛 코드의 비트를 재사용하면서 폐기 코드가 갑자기 활성화됐습니다. 45분 만에 잘못된 주문이 폭주했습니다.
기술적인 결함 이상으로 이 사건이 무서운 건, 그 뒤에 있는 부채의 방치입니다. "폐기된 코드는 나중에 치우자"가 "영원히 안 치운" 상태로 쌓여 있었고, 배포 절차서도 동료 검토도 없었습니다. Fowler의 사분면으로 옮기면, 이건 Inadvertent + Reckless의 전형입니다. 아무도 그게 시한폭탄이라고 생각하지 않았고, 아무도 그 점에 대해 이야기하지 않았습니다.
같은 "기술 부채"라는 말이 트위터에서는 성장의 도구였고, Knight Capital에서는 조직을 파괴한 지뢰였습니다. 차이는 부채 자체가 아니라, 부채가 인지되었는가, 상환 계획이 있었는가에 있었습니다. 그리고 그걸 묻는 사람이 바로 PM입니다.
기술 결정의 또 다른 축은 **"직접 만들 것인가, 사올 것인가"**입니다. 텃밭을 손질하는데 포크레인을 부르는 건 낭비고, 수 만 평을 개간하는데 삽만 쓰는 건 시간을 헛되게 쓰는 것입니다. 적정 장비의 판단이 필요합니다.
PM이 쥐어야 할 기준은 단순합니다.
원칙은 한 문장으로 요약됩니다.
핵심이면 만든다. 범용이면 산다.
HR 시스템, CRM, 빌링, 로그 수집, 에러 모니터링 — 이것들은 대부분의 회사에서 사는 편이 낫습니다. 잘 만들어진 시장 솔루션이 있고, 이걸 직접 만드는 데 드는 시간은 대개 회사의 차별화에 기여하지 않습니다. 반면 그 회사를 그 회사답게 만드는 부분은 사올 수 없습니다.
Shopify가 좋은 예입니다. Shopify는 핵심 커머스 엔진과 템플릿 언어 Liquid를 직접 만들었습니다. 이게 그들의 차별화였고, 16,000개 이상의 앱 생태계가 이 위에 쌓였습니다. 반면 물류는 한때 직접 해보려 했다가, 2023년 Flexport에 매각하며 방향을 틀었습니다. 물류는 핵심 차별화가 아니었고, Flexport가 더 잘하는 일이었습니다. 핵심은 Build, 비핵심은 Buy/Partner — 이 구분을 과감히 한 회사가 살아남습니다.
PM이 이 결정에 던져야 할 질문은 이것입니다.
"이것이 우리 회사를 우리답게 만드는 것인가요, 아니면 어느 회사나 필요한 것인가요?"
답이 전자면 삽을 듭니다. 후자면 포크레인을 빌립니다. 이걸 거꾸로 해서 실패하는 회사가 훨씬 많습니다. 차별화 영역을 외부 솔루션에 의존해서 혁신의 속도가 죽거나, 범용 영역을 직접 만들다가 차별화에 쓸 리소스를 소진하거나.
엔지니어가 "이 쿼리 3초 걸려요"라고 말할 때, PM은 이걸 제품의 언어로 바꿀 수 있어야 합니다.
몇 가지 숫자는 반드시 기억해야 합니다.
아마존(2006): 페이지 로드 100ms 지연 = 매출 1% 감소. 내부 A/B 테스트 결과.
구글(2006): 검색 결과 생성 시간 0.5초 추가 = 트래픽 20% 감소.
일반 웹: 페이지 로드 3초 이상이면 53% 이탈. 1초 로드 사이트는 5초 로드 대비 전환율 5배.
이 숫자들을 알면, "쿼리 3초"는 더 이상 엔지니어만의 언어가 아닙니다. 그것은 "사용자의 절반이 결과를 보기 전에 나갑니다"와 같은 말입니다. 그 순간 PM은 이 문제를 로드맵의 어디에 둘지 판단할 수 있습니다.
성능 이야기를 할 때 PM이 가져야 할 또 하나의 감각은 시간 복잡도입니다. 코드를 짤 필요는 없지만, O(n²)이 왜 무서운지는 감을 잡아야 합니다.
감을 잡아야 하는 건 이 표의 마지막 줄입니다. O(n)에서 O(n²)로 넘어가면 1만 건 기준으로 1만 배 차이가 납니다. 엔지니어가 "지금은 괜찮은데 사용자 1만 명 되면 터져요"라고 하는 건 이 차이를 말하는 것입니다. 지금의 로컬 테스트에서는 보이지 않지만, 사용자가 늘면 기하급수적으로 느려집니다.
이 감각이 없으면 PM은 "사용자 100명 때 괜찮았으니까 괜찮겠지"라고 믿고 출시 버튼을 누릅니다. 그리고 사용자 5,000명이 되는 날, 제품은 멈춥니다.
Healthcare.gov는 이 실패의 대표적 예입니다. 2013년 10월 1일 출시한 이 시스템은 예상의 5배인 25만 명이 접속하자 2시간 만에 다운됐습니다. 더 무서웠던 건 그 배경입니다. 원래 계정 없이 보험 상품을 조회할 수 있었지만, 기술 지연 때문에 기능이 삭제됐고 모든 사용자가 로그인을 거쳐야 했습니다.
그런데 로그인 시스템의 용량은 재산정되지 않았습니다. "기능 삭제"라는 제품 결정이 "로그인 시스템 확장"이라는 기술 결정을 유발해야 했는데, 그 연결고리가 끊어져 있었습니다. PM이 "지금 우리가 고른 이 경로의 병목은 어디인가?"를 물었다면 잡을 수 있었던 문제입니다.
기술 대화에 참여하기 시작한 PM이 곧바로 쓸 수 있는 도구가 두 개 있습니다.
ADR (Architecture Decision Record) — Michael Nygard가 2011년에 정리한 경량 문서입니다. 중요한 아키텍처 결정을 다섯 줄로 기록합니다.
Title: 결정의 제목 (예: "PostgreSQL을 메인 DB로 사용")
Status: Proposed / Accepted / Deprecated
Context: 왜 이 결정이 필요했는가 — 당시의 제약, 가정, 트레이드오프
Decision: 무엇을 결정했는가
Consequences: 긍정적·부정적 결과 모두
ADR의 중요한 점은 "왜"가 기록된다는 것입니다. 6개월 뒤, 새로 합류한 엔지니어가 "왜 이렇게 했지?"라고 물을 때, 답이 코드가 아닌 문서에 남아 있습니다. PM이 ADR을 직접 쓸 필요는 없지만, "이 결정, ADR에 남겨둡시다"라고 요청할 수는 있어야 합니다. 특히 일방통행 문에 가까운 결정일수록요.
Technical Spike — Kent Beck이 Extreme Programming Explained에서 명명한 기법입니다.
이름은 "설계 전체를 관통하는 스파이크를 박는다"는 비유에서 왔습니다. 시간제한이 있는 탐색 활동입니다.
엔지니어가 "이 기술, 가능할지 확실하지 않아서 더 조사해봐야 해요"라고 할 때, 무한정 조사하게 두면 안 됩니다. 그렇다고 "그냥 해"라고 밀어붙이면 배수 파이프를 터뜨립니다. 대신 이렇게 말합니다.
"그럼 스파이크를 잡읍시다. 이틀 드릴게요. 목적은 '이 방향이 가능한가/아닌가'를 결정하는 거고, 결과물은 프로덕션 코드가 아니라 추천안 한 장입니다. 이틀 뒤에 같이 봐서 Go/No-Go 결정합시다."
이 구조가 하는 일은 세 가지입니다. 첫째, 불확실성에 투자하는 것을 합법화합니다. "시간 낭비"가 아니라 "기간 정해진 탐사"로 인식됩니다. 둘째, 무한 탐색을 막습니다. 마감이 있으니 결정이 강제됩니다. 셋째, 코드가 아니라 지식이 결과물이라는 점을 분명히 해서, 탐색용으로 급하게 짠 코드가 그대로 프로덕션에 들어가는 사고를 방지합니다.
ADR과 스파이크, 이 두 개만 팀의 언어에 들어와도 기술 결정의 품질이 크게 바뀝니다. 둘 다 PM이 직접 하는 일은 아니지만, 요청할 수 있는 일입니다. 그리고 이걸 요청할 줄 아는 PM이 엔지니어링팀의 가장 고마운 동료가 됩니다.
지금 팀에서 제기된 기술적 우려 하나를 꺼내봅니다. "이거 O(n²)이에요", "이 쿼리 느려요", "리팩토링 먼저 해야 해요", "이 라이브러리 업그레이드 해야 돼요" — 아무거나 괜찮습니다.
다섯 질문을 던집니다. "지금 문제인가, 나중 문제인가?", "되돌릴 수 있는가?", "이 비용은 어디서 발생하는가?", "이것 없이 핵심 가치를 전달할 수 있는가?", "이 부채를 언제, 어떻게 갚을 건가?"
일방통행 문 / 양방향 문을 판정합니다. 이 기술 결정을 6개월 뒤에 되돌리려면 비용이 얼마나 드는지를 엔지니어에게 직접 물어봅니다. 답이 "한 스프린트"면 양방향, "수개월 + 데이터 마이그레이션"이면 일방통행.
부채라면, 사분면에 배치합니다. 의도적인가 모르고 있었나? 신중한 판단이었나 무모한 것이었나? 오른쪽 위(Deliberate + Prudent)가 아니면, 지금 대화를 시작해야 한다는 신호입니다.
상환 계획을 로드맵에 넣습니다. "다음 분기", "MAU 10만 도달 시점", "수익 지표 X 달성 후" 같은 구체적 트리거로. 상환 계획 없는 의도적 부채는 존재하지 않는 것과 같습니다.
일방통행 문이면 ADR을 요청합니다. "왜 이렇게 결정했는지 한 장만 남겨둡시다." 엔지니어가 이미 쓰고 있다면 더 좋고, 아니라면 이 기회에 습관을 들입니다.
다섯 단계를 모두 밟지 않아도 괜찮습니다.
다섯 질문 중 한 개만 제대로 던져도 대화의 방향이 바뀝니다.
"그래도 해"와 "알아서 해" 사이에 있는 제 3의 자리,
맥락을 제공하는 농부의 자리로 한 걸음 이동하는 것입니다.
이 장의 처음에 등장한 농부는 포크레인을 운전할 줄 몰랐습니다. 유압 용량도 몰랐고, 버킷의 효율적 동선도 몰랐습니다. 그러나 그는 자기 밭을 알았습니다. 어디에 파이프가 묻혀 있는지, 어떤 나무가 약한지, 올해 뭘 심을 계획인지. 그리고 그 맥락을 기사에게 전달할 줄 알았습니다.
PM의 자리도 정확히 거기입니다. 기술의 세부는 엔지니어의 영역입니다. 그러나 "여기 뭐가 있는지, 뭐가 중요한지, 어느 방향으로 가고 싶은지"는 PM이 전달해야 합니다. 이걸 전달하지 못하는 PM은 "알아서 해"라고 넘기거나 "그래도 해"라고 밀어붙이는 두 극단 사이에서만 움직이게 됩니다.
다섯 개의 질문, 두 종류의 문, 기술 부채의 사분면, Build vs. Buy의 기준, 밀리초의 의미, ADR과 스파이크. 이 여섯 가지만으로도 기술 대화의 언어가 생깁니다. 엔지니어가 "O(n²)이라 터져요"라고 말할 때, 당신은 이제 두 가지 중 하나로 반응하지 않아도 됩니다. 그 말을 제품과 사용자와 비즈니스의 지도 위에 올려놓고, 함께 결정할 수 있습니다.
"Shipping first time code is like going into debt.
A little debt speeds development so long as it is paid back promptly with a rewrite."
— Ward Cunningham, 1992
다음 장에서는, 가정을 심문하고 기술적 맥락까지 정리한 해결바카라을 실제 세계에 내놓는 방법을 이야기합니다. 전부 만들어 출시하는 것과, 가장 저렴한 방식으로 실패하는 것은 전혀 다른 규율입니다.
MVP, 프리토타입, Wizard of Oz, Fake Door. "가장 싸게 틀리는" 방식으로 검증하는 법,
그리고 그 실수들이 왜 제품의 수명을 늘리는지에 대해.