작은 팀이 제품 여러 개를 동시에 굴릴 때 필요한 우선순위 규칙
제품 수가 늘면 무엇이 가장 먼저 무너지는가
제품이 하나에서 셋으로 늘어날 때 가장 먼저 무너지는 것은 개발 속도가 아닙니다. 판단의 일관성입니다. 지난주 한 제품에서 내린 결정과 이번 주 다른 제품에서 내린 결정이 서로 어긋나기 시작하고, 어긋났다는 사실은 몇 주가 지나서야 드러납니다. 코드보다 맥락이 먼저 깨집니다. 팀은 바빠졌다고 느끼지만 무엇이 느려졌는지는 설명하지 못합니다.
제품마다 사용자가 다르고, 성공으로 볼 신호가 다르고, 배포 절차와 데이터 구조가 다릅니다. 오전에 출결 서비스의 근무 규칙을 들여다보다가 오후에 구인구직 서비스의 검색 정렬을 손대면, 두 작업 사이에서 잃는 것은 시간만이 아닙니다. 앞의 작업에서 막 잡아가던 감각이 사라집니다. 그 감각을 다시 세우는 데 드는 시간은 일정표에 항목으로 잡히지 않기 때문에, 팀은 자기가 얼마나 손해를 보고 있는지 끝까지 모릅니다.
두 번째로 무너지는 것은 대응 속도입니다. 제품이 하나일 때는 문의가 들어오면 누구나 답할 수 있습니다. 셋이 되면 답할 수 있는 사람이 한 명으로 좁혀지고, 그 사람이 다른 제품 작업에 들어가 있으면 답변은 하루씩 밀립니다. 밀린 답변은 그냥 늦은 답변으로 끝나지 않습니다. 같은 질문이 다시 들어오고, 사용자는 서비스가 관리되지 않는다고 판단하며, 대응 부담이 원래보다 커진 상태로 돌아옵니다.
세 번째는 기록입니다. 제품이 하나일 때는 문서가 부실해도 머릿속 기억으로 메울 수 있습니다. 여러 개가 되면 기억이 서로 섞이기 시작합니다. 배포 절차를 잘못 기억해 스테이징에 올려야 할 것을 운영에 올리는 사고는, 실력이 부족해서가 아니라 세 벌의 절차를 한 사람의 기억에 얹어두었기 때문에 일어납니다.
지금 팀이 이 지점에 있는지 확인하는 방법은 간단합니다. 이번 주에 무엇을 하고 있는지 각자에게 따로 물어보십시오. 답이 사람마다 다르면 이미 문제가 시작된 것입니다. 어떤 제품이 지금 가장 중요한지 물었을 때 두 명 이상이 서로 다른 제품을 말한다면, 우선순위는 존재하지 않는 상태입니다. 모두가 열심히 일하는데 아무것도 끝나지 않는 시기가 여기서 시작됩니다.
저희도 같은 구간을 지났습니다. 여우비 인터랙션은 출결 관리 서비스 onSpots, 한국어를 배우는 사람과 가르치는 사람을 잇는 매칭과 맵핑 서비스인 랭토리, 베트남 구인구직 서비스 Job Connect VN, 그리고 소상공인의 매장 운영을 돕는 위니를 함께 다루면서 고객사 개발도 병행합니다. 문제는 만들 사람이 모자란다는 데 있지 않았습니다. 제품마다 다른 판단 기준을 같은 머릿속에 동시에 얹으려 했다는 데 있었습니다. 그래서 사람을 더 붙이는 대신 규칙을 먼저 정했습니다.
동시에 굴릴 수 있는 개수에는 한계가 있다
동시에 굴릴 수 있는 제품 수는 인원 수로 정해지지 않습니다. 살아 있는 결정 라인의 수로 정해집니다. 결정 라인이란 누군가 매주 판단을 내려야 하는 흐름을 말합니다. 사람을 늘려도 한 사람이 붙들고 있는 결정 라인이 둘을 넘으면 결정의 질이 떨어집니다. 개수의 상한은 여기서 나옵니다.
제품 하나는 코드 한 벌이 아니라 상시 부하입니다. 신규 기능을 한 줄도 만들지 않아도 부하는 0이 되지 않습니다. 스토어 심사 정책이 바뀌고, 운영체제가 올라가면서 예전 방식이 막히고, 의존성에 보안 패치가 뜨고, 인증서와 도메인 만료가 돌아오고, 문의가 들어오고, 인프라 청구서가 매달 발생합니다. 이 부하는 제품을 만들 때가 아니라 살려둘 때 발생합니다. 그래서 제품을 추가한다는 결정은 개발 일정을 늘리는 결정이 아니라, 앞으로 매주 반복될 고정 부하를 하나 더 짊어지는 결정입니다.
여기서 슬롯이라는 개념이 필요합니다. 팀이 가진 자리를 능동 개발, 유지, 실험 세 종류로 나누고 각각의 개수를 고정합니다. 능동 개발 슬롯은 신규 기능과 개선이 실제로 들어가는 자리입니다. 유지 슬롯은 살아 있되 신규 기능이 들어가지 않는 자리입니다. 실험 슬롯은 기간을 정해두고 배움을 목적으로 돌리는 자리입니다. 핵심은 능동 개발 슬롯의 총량을 고정하는 데 있습니다. 새 제품을 능동 개발로 올리려면 지금 능동 개발에 있는 제품 하나를 유지로 내려야 합니다. 이 교환을 강제하지 않으면 능동 개발 목록은 계속 길어지고, 길어진 목록은 결국 아무것도 진행되지 않는 목록이 됩니다.
진행 중인 일의 총량을 먼저 제한하는 방식은 새로운 발상이 아닙니다. 제조와 소프트웨어 양쪽에서 오래 쓰여온 접근입니다. 작은 팀에서 이 방식이 특히 잘 듣는 이유는, 사람 수가 적을수록 한 사람이 여러 흐름에 걸쳐 있을 확률이 높고 그만큼 맥락 전환 손실이 크기 때문입니다.
유지 모드는 말로만 두면 지켜지지 않습니다. 문서로 정의해야 합니다. 유지 모드에서 허용되는 작업은 장애 대응, 보안 업데이트, 스토어와 플랫폼 정책 대응, 그리고 데이터 손실을 막는 조치까지입니다. 신규 기능은 들어가지 않습니다. 문구 하나만 바꾸면 되는 요청, 화면 하나만 추가하면 되는 요청이 유지 모드를 갉아먹습니다. 작은 요청은 작게 끝나지 않습니다. 테스트가 따라오고 배포가 따라오고 회귀 확인이 따라옵니다. 유지 모드를 정의할 때는 해제 조건도 같이 적어두십시오. 어떤 조건이 충족되면 다시 능동 개발로 올릴지 미리 정해두면, 담당자가 규칙을 어기지 않고도 기다릴 수 있습니다.
상한을 감으로 정하지 마시고 기록으로 정하십시오. 두세 주 동안 제품별로 실제 들어간 시간을 적어보면, 신규 기능과 무관하게 매주 고정으로 나가는 시간이 보입니다. 그 고정 시간의 합이 팀이 쓸 수 있는 시간의 절반을 넘어가면, 새 제품을 붙일 여력은 이미 없습니다. 이 계산은 추정으로 하면 항상 낙관적으로 나옵니다. 실제로 적어야 합니다.
우선순위를 정하는 세 축: 살아남을 것, 배울 것, 유지비
우선순위를 매출 전망 하나로 정하면 대부분 틀립니다. 세 축을 같이 봐야 합니다. 첫째는 살아남을 가능성, 둘째는 그 제품에서만 배울 수 있는 것, 셋째는 가만히 둬도 나가는 유지비입니다. 목적은 점수를 매기는 것이 아니라 순서를 만드는 것입니다.
첫 번째 축인 살아남을 가능성은 희망이 아니라 신호로 판단합니다. 문제는 무엇을 신호로 볼지 대개 제품을 시작할 때가 아니라 결과를 봐야 할 때 정한다는 데 있습니다. 그때 정하면 이미 있는 숫자 중에 유리한 것을 고르게 됩니다. 시작 시점에 정해두십시오. 반복해서 돌아오는 사용자가 있는지, 들어오는 문의가 불만인지 기능 요구인지, 아무도 안내하지 않았는데 스스로 찾아 쓰는 흐름이 있는지 같은 것들입니다. 기능 요구가 들어온다는 것은 사용자가 그 제품을 계속 쓸 생각이 있다는 뜻이라 불만보다 좋은 신호입니다. 신호를 정할 때는 반드시 관찰 기간도 같이 적으십시오. 기간이 없으면 판단은 무한히 미뤄집니다.
두 번째 축인 배울 것은 작은 팀에서 특히 중요합니다. 제품 하나가 당장 돈이 되지 않더라도, 그 제품을 만들면서 얻은 역량이 다른 제품으로 옮겨간다면 그 투자는 회수됩니다. 다국어와 로케일 처리를 제대로 한 번 해보면 다음 제품에서는 설계 단계부터 다르게 잡습니다. 스토어 심사를 여러 번 통과해보면 반려 사유를 미리 피하는 습관이 생깁니다. 두 나라에 걸친 서비스에서 시간대와 표기 규칙을 다뤄보면 그 경험은 사라지지 않습니다. 다만 배울 것을 근거로 유지하는 제품에는 반드시 기한을 붙이십시오. 기한 없는 학습은 그냥 방치입니다.
세 번째 축인 유지비는 돈만 세면 안 됩니다. 인프라 비용은 청구서에 찍히기 때문에 누구나 보지만, 실제로 더 비싼 것은 주의력입니다. 매주 확인해야 할 대시보드가 하나 늘고, 매달 대응해야 할 정책 변경이 하나 늘고, 장애가 났을 때 원인을 찾는 데 필요한 배경 지식이 한 벌 늘어납니다. 주의력은 돈처럼 나중에 더 벌어올 수 없습니다. 유지비를 볼 때는 이번 달 청구액이 아니라 이 제품이 앞으로 매주 가져갈 사람의 관심을 보십시오.
세 축이 서로 다른 답을 낼 때가 진짜 판단 지점입니다. 여기서 세 축에 가중치를 매겨 합산하는 방식은 권하지 않습니다. 합산은 결론을 먼저 정해놓고 가중치를 맞추는 일로 흘러가기 쉽습니다. 대신 조합별 대응을 미리 정해두십시오. 살아남을 신호가 약한데 배울 것이 크면 기한을 정한 실험으로 내립니다. 신호가 강한데 유지비가 크면 유지비를 줄이는 작업 자체를 그 분기의 과제로 올립니다. 신호가 약하고 배울 것도 없는데 유지비만 나가면 다음 절의 멈춤 규칙 대상입니다. 신호가 강하고 배울 것도 크면 그것이 능동 개발 슬롯에 들어갈 제품입니다.
순서를 정한 뒤에는 그 순서를 글로 적어 팀이 볼 수 있는 곳에 두십시오. 머릿속에만 있는 우선순위는 다음 회의에서 목소리가 큰 사람의 안건으로 바뀝니다. 적어두면 바꾸는 데 이유가 필요해지고, 이유를 대야 하면 즉흥적인 변경이 줄어듭니다.
담당을 나누는 방식: 한 사람이 한 제품을 끝까지 맡는 이유
한 제품을 여러 사람이 조금씩 나눠 맡으면, 총 투입 시간이 같아도 결과는 나빠집니다. 맥락을 다시 세우는 시간이 사람 수만큼 늘어나고 결정이 계속 미뤄지기 때문입니다. 한 사람이 요구 정리부터 개발과 배포, 사후 대응까지 맡을 때 판단이 빨라지고 책임의 위치가 분명해집니다.
끝까지 맡는다는 말의 범위를 먼저 정해야 합니다. 요구사항을 정리하고, 만들고, 배포하고, 사용자 문의의 1차 대응을 하고, 그 제품의 문서를 최신으로 유지하는 것까지입니다. 이 범위를 좁게 잡으면 전담제는 이름만 남습니다. 개발만 전담하고 대응은 다른 사람이 하면, 대응하는 사람은 매번 물어봐야 하고 개발하는 사람은 매번 하던 일을 멈춰야 합니다. 두 사람 모두 손해를 봅니다.
전담제를 말하면 곧바로 나오는 반론이 있습니다. 그 사람이 없으면 어떻게 하느냐는 것입니다. 정당한 지적이고, 전담제 자체를 포기할 이유는 아닙니다. 세 가지로 막을 수 있습니다. 제품마다 백업 담당을 지정하되 백업은 평소에 개발하지 않고 문서를 읽을 수 있는 상태만 유지합니다. 배포와 복구 절차는 사람의 기억이 아니라 문서와 스크립트에 둡니다. 그리고 분기마다 한 번은 백업 담당이 실제로 배포를 한 번 해봅니다. 문서가 맞는지는 읽어서는 알 수 없고 돌려봐야 압니다.
리더가 해야 할 일은 담당자에게 결정 권한을 실제로 넘기는 것입니다. 전담제를 선언해놓고 모든 결정을 리더가 승인하면, 담당자는 여전히 전달자이고 병목은 그대로입니다. 어떤 결정을 담당자가 혼자 내려도 되는지 미리 선을 그어두십시오. 대개 화면 구성, 구현 방식, 소규모 개선의 순서는 담당자가 정해도 문제가 없습니다. 과금 구조, 데이터 보관 정책, 외부 공개 일정처럼 되돌리기 어려운 것만 위로 올리면 됩니다. 이 선이 없으면 모든 결정이 위로 올라오고, 리더는 운영 중인 모든 제품의 세부 사항을 동시에 판단하는 자리에 서게 됩니다. 그 자리에서 나오는 결정은 좋을 수가 없습니다.
전담으로 나누면 안 되는 것도 있습니다. 인증, 보안 기준, 배포 파이프라인, 디자인 토큰과 공통 컴포넌트처럼 제품마다 다르게 만들면 손해인 것들입니다. 이것들은 공통 층으로 뽑아 한 번 정하고 모두가 따르게 하십시오. 제품별로 따로 만들면 세 벌을 관리해야 하고, 보안 이슈가 생겼을 때 세 곳을 고쳐야 합니다. 반대로 이 공통 층을 지나치게 크게 잡으면 제품마다 필요한 유연성이 죽습니다. 경계를 정하는 기준은 간단합니다. 잘못됐을 때 피해가 제품 하나에 그치면 제품 안에 두고, 여러 제품으로 번지면 공통 층으로 올립니다.
전담제의 약점은 배움이 갇힌다는 점입니다. 각자 자기 제품만 보면 팀 전체의 기술 수준이 고르게 오르지 않습니다. 정기적으로 짧게 공유하는 자리를 만드십시오. 이번에 막혔던 지점 하나와 해결한 방식 하나를 말하는 정도면 충분합니다. 발표 자료를 만들게 하면 아무도 하지 않게 되므로, 형식을 가볍게 유지하는 편이 오래갑니다.
멈춤을 결정하는 규칙이 있어야 한다
시작 규칙만 있고 멈춤 규칙이 없는 팀은 제품을 계속 쌓습니다. 멈춤 조건을 제품을 시작할 때 미리 적어두면 나중에 감정을 빼고 결정할 수 있습니다. 멈춤은 실패 선언이 아니라 슬롯을 비우는 운영 행위입니다. 비워야 다음을 시작할 수 있습니다.
멈춤에는 세 단계가 있고 이 셋을 구분하지 않으면 논의가 늘 극단으로 갑니다. 첫째는 유지 모드 전환입니다. 서비스는 그대로 돌아가고 신규 개발만 멈춥니다. 둘째는 보류입니다. 신규 가입이나 신규 유입을 닫고 기존 사용자만 유지합니다. 셋째는 종료입니다. 서비스를 내리고 데이터를 정리합니다. 대부분의 상황에서 필요한 것은 첫째나 둘째인데, 멈춤이라는 말이 곧바로 셋째로 이해되기 때문에 논의가 어려워집니다. 세 단계에 각각 이름을 붙여두면 대화가 훨씬 수월해집니다.
제품을 시작할 때 세 가지를 같이 적어두십시오. 관찰 기간을 언제까지로 볼 것인지, 그 기간에 무엇을 보면 계속 간다고 판단할 것인지, 그 신호가 나오지 않으면 위 세 단계 중 어디로 내릴 것인지입니다. 이 세 줄을 시작 시점에 적는 데 드는 시간은 길지 않습니다. 나중에 적으려 하면 이미 애착과 매몰비용이 붙어 있어 어떤 기준도 합의되지 않습니다.
멈추기로 했다면 멈추는 일 자체를 하나의 작업으로 다뤄야 합니다. 그냥 손을 떼는 것은 멈춤이 아니라 방치입니다. 사용자에게 언제부터 무엇이 달라지는지 미리 알리고, 사용자가 자기 데이터를 가져갈 방법을 열어두고, 스토어 등록 상태를 정리하고, 도메인과 인증서 만료를 확인하고, 남은 인프라를 끄고, 다시 열 가능성이 있다면 다시 열기 위해 필요한 것을 문서로 남깁니다. 이 마무리를 제대로 하지 않으면 멈춘 제품이 계속 비용과 주의력을 가져갑니다. 멈춘 줄 알았는데 매달 청구서가 오는 상황이 여기서 나옵니다.
이 판단을 즉흥적으로 하지 않으려면 자리를 정례로 만드는 편이 낫습니다. 분기에 한 번, 운영 중인 제품 전부를 놓고 세 축을 다시 보고 슬롯 배치를 조정합니다. 이 자리에서 아무것도 바뀌지 않는 분기도 있습니다. 그래도 자리를 없애지 마십시오. 정례가 아니면 멈춤 논의는 문제가 이미 커진 뒤에야 시작되고, 그때는 선택지가 종료 하나만 남습니다.
여기서 다루는 멈춤 규칙은 특정 제품을 겨냥한 절차가 아니라 운영 장치입니다. 어떤 제품을 접겠다는 예고와는 다른 이야기입니다. 규칙을 미리 만들어두는 목적은 오히려 반대쪽에 있습니다. 멈추는 방법이 정해져 있으면 새로운 시도를 시작하기가 쉬워집니다. 되돌릴 수 없다고 느낄 때 팀은 시작을 미루고, 되돌리는 절차가 있으면 작게 빨리 시작합니다. 우선순위 규칙과 멈춤 규칙은 팀을 소극적으로 만들기 위한 것이 아니라, 적은 인원으로 여러 제품을 계속 굴리면서도 판단의 질을 지키기 위한 최소한의 장치입니다.