구글에서 14년간 엔지니어로 일하며 얻은 교훈을 추가로 정리한 글로, 뛰어난 코드를 작성하는 것 이상으로 정말 중요한 것들이 무엇인지 다룬다.
얼마 전 구글에서 일하며 배운 21가지 교훈을 정리한 적이 있다. 반응은 예상 밖이었는데, 특히 사람들에게 와닿은 건 기술적인 조언이 아니었다. 사람, 의사결정, 그리고 함께 무언가를 만들어가는 과정의 지저분한 현실에 관한 이야기들이었다.
그제서야 아직 하지 못한 이야기가 많다는 걸 깨달았다. 첫 번째 목록은 개인의 역량에 초점이 맞춰져 있었다. 더 좋은 코드를 작성하는 법, 커리어를 어떻게 바라볼 것인가 같은 것들. 하지만 내가 가장 힘겹게 배운 교훈들은 '나'의 일하는 방식에 관한 게 아니었다. '팀'이 어떻게 돌아가는지에 관한 것이었다. 실제로 의사결정이 이루어지는 과정, 협업이 무너지는 지점, 결과물을 내는 팀과 제자리만 맴도는 팀의 차이 같은 것들 말이다.
이번 교훈들은 첫 번째 글의 연장선에 있다. 더 나은 개인 엔지니어가 되는 법보다는, 엔지니어링을 둘러싼 시스템에 관한 이야기다.
무언가에 '예스'라고 말하는 순간, 다른 무언가에 암묵적으로 '노'라고 말하는 것이다.
실력 있는 엔지니어들이 모든 것에 '예스'하다가 번아웃되는 걸 여러 번 봤다. 버그 하나, 기능 요청 하나, "금방 끝나는 부탁" 하나. 그러다 보면 캘린더가 다른 사람의 우선순위로 가득 차고, 자기 로드맵은 반쯤 완성된 아이디어의 무덤이 된다.
때로는 제품에 대한 애정이 진심으로 클수록 그렇게 되기 쉽다. 프로덕션 환경을 장애로부터 보호하듯, 자신의 역량도 "있으면 좋은 것"으로부터 지켜야 한다. 핵심은 올바른 일을 하고, 그렇지 않은 일은 하지 않은 채로 두는 기술이다.
비례 이상의 임팩트를 만들어내는 엔지니어들이 반드시 더 빠르거나 더 똑똑한 건 아니다. 무엇에 주의를 기울일지에 대해 더 냉정할 뿐이다. 잘못된 일에 시간을 쓰는 대가는 결국 잘못된 일에 시간을 쓴 것 자체라는 사실을 이미 깨우친 사람들이다.
대부분의 회의가 실패하는 이유는 불필요해서가 아니라, 변장한 독백이기 때문이다. 똑똑한 사람들이 문제를 빙빙 돌려 말하면서도 정작 무엇이 필요한지 한 번도 명확히 말하지 않는 회의에 수백 시간을 앉아 있었다. 회의는 분위기만 남기고, 담당자 없이 끝나 버린다.
나는 요청부터 시작하는 법을 배웠다. 승인(approve), 선택(choose), 블로커 해소(unblock), 공유(inform).
이 네 단어만으로 회의 준비 방식이 완전히 바뀌었다. 하나도 고를 수 없다면, 다른 사람의 시간을 빼앗을 준비가 안 된 거다. 반대로 내가 회의에 초대받은 쪽이면, 첫 2분 안에 "저한테 어떤 결정이 필요하신 건가요?"라고 묻기 시작했다. 직설적으로 들릴 수 있지만, 대부분 오히려 안도한다. 자기 자신도 무엇이 필요한지 정의하지 못했다는 걸 그때서야 깨닫는 경우가 많기 때문이다.
모호한 회의의 숨은 비용은 그 한 시간이 아니다. 아무도 명확히 정리해주지 않은 채, 한 주 내내 방향 없이 흘러가는 시간이다.
움직임과 진전의 차이는 구체성에 있다.
팀은 의도의 바다에 빠진다. 로드맵에 "온보딩 흐름을 개선해야 한다", "지연 시간을 줄여야 한다", "API를 문서화해야 한다" 같은 항목들이 빼곡히 채워지지만, 몇 달 뒤에도 같은 항목이 먼지와 죄책감만 쌓인 채 그대로 남아 있는 걸 봤다. 에이전트 기반 엔지니어링이 등장한 지금은 해결된 문제라고 생각할 수도 있겠지만, 아직은 아니다.
말을 실제로 실행 가능한 가장 작은 다음 행동으로 바꾸고, 거기에 이름과 날짜를 붙여라. "온보딩을 개선해야 한다"가 아니라, "화요일에 Sarah가 사용자 세션 3회를 진행하고 핵심 마찰 지점을 문서화한다"처럼.
이건 사람에게는 발판이 있어야 앞으로 나아갈 수 있다는 사실을 존중하는 것이다. 막연한 의도는 불안을 만들고, 구체적인 약속은 추진력을 만든다. 계획이 완벽할 필요는 없다. 누군가 실제로 시작할 수 있을 만큼만 구체적이면 된다.
속도란, 똑똑한 사람들이 머뭇거리게 만드는 마찰을 제거하는 것이다. 가능하다면 "행동 우선"을 택하라.
프로젝트가 지지부진할 때, 본능적으로 실행 속도를 탓하게 된다. 사람들이 충분히 열심히 안 한다, 코드베이스가 엉망이다, 엔지니어가 부족하다. 하지만 내 경험상 느린 코드는 증상에 불과한 경우가 많다. 진짜 병은 느린 의사결정이다.
결정이 습관적으로 몇 주, 몇 달씩 걸린다면 더 깊이 들여다봐야 한다. 맥락이 부족하면 사람들은 트레이드오프를 판단할 수 없다. 오너십이 불분명하면 모두가 다른 누군가의 결정을 기다린다. 책임에 대한 두려움이 크면 확실한 결정 대신 애매하게 보험을 건다.
내가 함께 일했던 가장 빠른 엔지니어링 팀은 최고의 프로그래머가 모인 팀이 아니었다. 권한이 명확하고, 맥락이 공유되어 있고, 틀려도 커리어에 위험이 되지 않는 환경 덕분에 의사결정이 몇 주가 아니라 몇 시간 만에 이루어지는 팀이었다.
사용자는 안정성을 칭찬하지 않지만, 안정성이 사라진 순간은 바로 알아챈다.
이것이 위험한 역학을 만든다. 안정성 관련 작업은 문제가 생기기 전까지 보이지 않고, 그래서 눈에 띄는 신규 기능에 비해 항상 리소스가 부족하다.
에러 버짓(error budget)은 이 트레이드오프를 명시적으로 만드는 한 가지 방법이다. 서비스의 SLO가 99.9% 가용성이라면, 혁신에 쓸 수 있는 0.1%의 다운타임 "예산"이 있는 셈이다. 예산을 다 소진하면, 다시 확보할 때까지 안정성에 집중한다. 이것은 리스크에 대해 솔직한 대화를 나누기 위한 프레임워크다.
속도와 안정성을 동시에 유지하는 팀은 영웅적 희생으로 버티는 게 아니다. 안정성을 고유한 로드맵, 고유한 지표, 고유한 담당자를 가진 일급(first-class) 제품 기능으로 취급하기 때문이다.
제품 리뷰 없이 기능을 출시하지는 않을 것이다. 시스템도 안정성 논의 없이 출시해서는 안 된다.
팀 간 상호작용 모드에는 이유가 있다. 협업(긴밀하게 함께 일하기), 서비스(명확한 API와 SLA), 퍼실리테이션(한 팀이 다른 팀의 역량 구축을 돕기).
팀 간 마찰의 원인은 대부분 노력 부족이나 선의의 결핍이 아니다. 불명확한 경계와 지저분한 계약 관계가 문제다. 팀들이 "소통을 개선"한답시고 회의를 늘리고, Slack 채널을 추가하고, 싱크 미팅을 잡는 걸 봤는데, 상황은 나아지지 않았다.
문제는 대화가 부족한 게 아니다. 팀 간 인터페이스가 정의되지 않은 것이다. 누가 무엇을 소유하는가? 계약 관계는 어떠한가? A팀이 B팀에게 기대할 수 있는 건 무엇이고, 그 반대는 무엇인가?
이 모드를 의도적으로 선택하면, 일이 돌아가게 만드는 데 필요한 회의가 줄어든다. 나쁜 인터페이스를 소통으로 덮으려 하면, 가장 협조적인 사람들만 지치고 근본적인 문제는 그대로 남는다.
"이런 문제가 있습니다"는 절반만 한 것이다. 예전에는 이슈를 파악해서 리더십에 가져다주는 것이 내 역할이라고 생각했다. 물론 필요한 일이지만 그것만으로는 부족하다.
"두 가지 선택지가 있고, 트레이드오프는 이러하며, 제가 추천하는 건 이것입니다"라고 말해야 블로커가 해소되고 신뢰를 쌓을 수 있다. 이미 충분히 고민했다는 걸 보여주는 것이다. 의사결정자에게 열린 문제를 던지는 대신, 구체적으로 반응할 수 있는 무언가를 제공하는 것이다.
상대의 일을 쉽게 만들어주면, 상대가 내게 필요한 것을 줄 가능성도 높아진다.
"도움이 필요합니다"와 "A와 B 중에서 골라주세요, B를 추천하는 이유는 이렇습니다" 사이의 차이는 문제를 제기하는 사람과 문제를 해결하는 사람의 차이다.
둘 다 이슈를 식별하기는 한다. 하지만 점점 더 큰 신뢰와 자율성을 얻는 쪽은 하나뿐이다.
영웅은 번아웃 상태이고, 문서화되지 않은 존재이며, 단일 장애 지점이다.
한 사람이 위기를 구해내는 일이 반복되는 패턴이라면, 그건 자랑이 아니라 장애 모드다. 팀이 영웅을 축하하면서, 영웅이 필요하게 만든 구조적 문제는 외면하는 경우를 여러 번 봤다.
그 영웅이 떠나면—결국 언젠가는 다 떠난다—아무도 시스템이 어떻게 돌아가는지 모른다는 사실이 드러난다. 영웅에 대한 찬양은 시스템적 문제를 가린다. "평범한 사람이 평범한 날에" 돌릴 수 있는 경로가 작동하지 않는다는 문제를.
정상적인 경로가 기본이 되게 하라. 시스템을 문서화하고, 지식을 분산시키고, 예외적인 위기가 아니라 평범한 화요일을 기준으로 설계하라. 영웅은 불필요해야 하며, 만약 필요하다면 불필요하게 만드는 작업을 지금 당장 시작해야 한다.
텔레메트리 없는 기능은 위장된 부채다.
프로덕션에서 어떻게 동작하는지 모르는 채로 기능을 출시했다면, 불확실성을 출시한 것이다.
출시를 축하하고 몇 주 뒤에야 사용자 20%에게 기능이 조용히 실패하고 있었다는 걸 발견한 팀을 봤다. 로그도 없고, 지표도 없고, 대시보드도 없었다. 이해가 있어야 할 자리에 공백만 있었다. 이걸 나중에 고치려면 온갖 고통이 따르는데, 관측 가능성을 갖추고 제대로 A/B 테스트하기 위해 기능을 아예 롤백해야 하는 경우도 있다.
로그, 트레이스, 대시보드, 알림은 "운영 업무"가 아니다. 학습 수단이다. 내가 만든 것이 실제 환경에서 실제 사용자에게 실제로 동작하는지 확인하는 방법이다.
내가 아는 최고의 엔지니어들은 관측 가능성을 완료 정의(definition of done)의 일부로 본다. "코드를 작성했다"가 아니라 "코드를 작성했고, 동작하는 것을 눈으로 확인할 수 있다"가 완료인 것이다.
작은 변경은 리뷰하기 쉽고, 이해하기 쉽고, 되돌리기 쉽다.
예전에는 큰 풀 리퀘스트를 즐겨 올렸다. 하나의 완성된 기능을 한 번에 리뷰할 수 있다는 점이 좋았다. 내 편의를 위해 리뷰어의 정신 건강을 희생시킨 셈이었다. 작은 PR이 모두에게 더 나은 경우가 많다.
작은 PR은 더 빨리 머지된다. 누군가 천 줄짜리 diff를 이해할 한 시간을 확보하느라 리뷰 대기열에 방치되지 않기 때문이다. 동료가 당신의 속도를 신뢰하길 원한다면, 리뷰 가능한 크기로 만들어라.
숨겨진 이점도 있다. 작은 PR은 점진적으로 사고하도록 강제한다. 하나의 거대한 변경 대신, 역량을 조각조각 쌓아간다. 각 조각은 피드백을 받고, 각 조각은 독립적으로 롤백할 수 있다. PR 한 건당은 느리지만, 실제 프로덕션 반영까지는 더 빠르다.
조율 비용은 인원수보다 빠르게 증가한다.
"사람을 더 투입하면 된다"가 자주 실패하는 이유가 바로 이것이고, 프로젝트 후반에 인원을 추가하면 오히려 더 늦어지는 이유이기도 하다. 새로 합류한 사람은 협업해야 하는 모든 사람과 커뮤니케이션 오버헤드를 추가한다. 그래프는 단순히 커지는 게 아니라 밀도가 높아진다.
팀 규모가 두 배가 됐는데 산출물은 거의 그대로인 상황에 진심으로 당혹스러워하는 매니저를 봤다. 답은 항상 같다. 새로 생긴 엣지가 새로 확보한 역량을 잡아먹은 것이다. 사람이 늘어난 만큼 얼라인먼트 미팅, 맥락 공유, 더 많은 이해관계자가 필요한 의사결정 대기 시간도 함께 늘어났다.
해법은 채용을 멈추는 것이 아니라, 엣지를 줄이는 데 의도적으로 집중하는 것이다. 명확한 오너십. 의존성이 최소화된 자율적 팀. 보조를 맞춰야 하는 대신 병렬로 일할 수 있게 해주는 인터페이스. 최고의 조직은 사람이 가장 많은 조직이 아니라, 1인당 레버리지가 가장 높은 조직이다.
모든 마이그레이션은 현재 가진 시스템, 원하는 시스템, 그리고 둘 다 요청한 적 없는 사람들 사이의 협상이다.
한 분기로 예상했던 마이그레이션이 수년으로 늘어나는 걸 봤다. 기술적 작업이 잘못돼서가 아니라, 인적 작업을 아무도 고려하지 않았기 때문이다. 다른 팀들이 자기 로드맵 대신 이 마이그레이션을 우선순위에 올리도록 설득하는 일, 아무도 존재를 몰랐던 엣지 케이스의 롱테일을 지원하는 일, 그리고 죽지 않는 구 시스템과 신 시스템을 동시에 운영하는 일.
기술적 계획은 쉬운 부분이다. 어려운 건 공존을 설계하는 것이다. 예상보다 오래 신구 시스템을 동시에 운영하게 될 것이다. "레거시" 시스템이 아무도 문서화하지 않은 결정들과, 아무도 설계한 기억이 없지만 모두가 의존하는 워크플로를 내포하고 있다는 걸 발견하게 될 것이다. 모든 팀이 한꺼번에 하던 일을 멈추지 않아도 되는 도입 전략이 필요할 것이다.
실제로 완료되는 마이그레이션에는 세 가지 공통점이 있다. 킥오프 이후에도 계속 관여하는 스폰서, 마이그레이션을 사이드 퀘스트가 아니라 본업으로 맡는 전담 팀, 그리고 사람들이 진짜라고 믿는 명확한 폐기 일정. 셋 중 하나라도 빠지면, 마이그레이션은 영원히 "거의 다 됐는데"인 상태에 머문다. 이건 시작하지 않는 것보다 더 나쁘다. 두 시스템의 비용을 무기한으로 치르게 되기 때문이다.
끝까지 밀고 갈 비용을 투자할 의지가 없다면, 마이그레이션을 시작하지 마라.
이제 누구나 코드를 생성할 수 있다. 코드, 콘텐츠, 디자인을 만들어내는 진입 장벽이 급격히 무너지고 있다. 예전에 하나를 작성하던 시간에 AI가 열 가지 버전을 뽑아낸다.
차별화 요소는 선택이다. 무엇을 만들고, 무엇을 삭제하고, 무엇을 단순화하고, 무엇을 출시하지 않을 것인지, 그리고 "좋은 것"이 무엇인지 판단하는 능력. 안목(taste)—선택지를 구분하고 올바른 것을 고르는 능력—이 희소 자원이 된다.
AI로 빠르게 선택지를 탐색한 뒤, 판단력을 냉정하게 적용하라. 이 환경에서 성공하는 엔지니어는 가장 많이 생성하는 사람이 아니라, 가장 잘 골라내는 사람이다.
생산은 싸졌다. 편집은 비싸졌다. 선별이 전부다.
당신이 쌓을 수 있는 가장 레버리지 높은 것. 시스템이 아니라, 신뢰(credibility)다.
사람들이 당신을 신뢰하면, 의사결정 하나에 회의 다섯 번이 필요하지 않다. 역량, 선의, 실행력을 전제로 깔아주기 때문이다. 신뢰가 낮은 환경에서 몇 주 걸릴 결정이, 신뢰가 높은 환경에서는 몇 시간이면 끝난다.
약속을 지킬 때마다, 실수를 솔직히 인정할 때마다, 다른 사람의 일을 조금이라도 더 쉽게 만들어줄 때마다, 수년간 이자를 돌려줄 계좌에 입금하는 셈이다.
기술적 역량은 보통이지만 모두의 신뢰를 받아 엄청난 성과를 낸 엔지니어를 봤다. 뛰어난 실력을 갖추고도 아무도 전화를 받아주지 않아 별다른 성과를 내지 못한 엔지니어도 봤다.
함께 출시해줄 사람이 없다면, 아무리 좋은 코드도 의미가 없다.
지난번 글에서 나는 이 교훈들이 결국 호기심을 유지하고, 겸손함을 유지하고, 일의 중심에는 사람이 있다는 것을 기억하는 것으로 귀결된다고 했다. 지금도 그 생각은 같다.
다만 이번 두 번째 목록을 관통하는 메시지가 있다면, 좀 더 구체적인 것이다. 일이란 결국, 평범한 사람이 평범한 날에 비범한 일을 할 수 있도록 만들어주는 것이다. 엔지니어로서의 커리어는 이런 것들을 고생하면서 배울 시간을 충분히 준다. 나 역시 구글에서 지금까지 보낸 시간 동안 정말 많은 걸 배웠다.

이 글의 몇 가지가 당신의 시행착오를 하나라도 줄여줄 수 있기를 바란다. 그리고 만약 그렇다면, 당신이 깨달은 것을 여정의 앞쪽에 있는 누군가에게 나눠주길 바란다.
좋은 교훈은 그렇게 전해진다.