
칸반: 포스트잇의 마법
가장 단순하지만 가장 강력한 업무 관리법. To Do, Doing, Done. WIP(동시 작업 제한)로 병목 현상을 뚫어보자.

가장 단순하지만 가장 강력한 업무 관리법. To Do, Doing, Done. WIP(동시 작업 제한)로 병목 현상을 뚫어보자.
내 서버는 왜 걸핏하면 뻗을까? OS가 한정된 메모리를 쪼개 쓰는 처절한 사투. 단편화(Fragmentation)와의 전쟁.

미로를 탈출하는 두 가지 방법. 넓게 퍼져나갈 것인가(BFS), 한 우물만 팔 것인가(DFS). 최단 경로는 누가 찾을까?

이름부터 빠릅니다. 피벗(Pivot)을 기준으로 나누고 또 나누는 분할 정복 알고리즘. 왜 최악엔 느린데도 가장 많이 쓰일까요?

매번 3-Way Handshake 하느라 지쳤나요? 한 번 맺은 인연(TCP 연결)을 소중히 유지하는 법. HTTP 최적화의 기본.

첫 스타트업을 운영하던 때였다. 개발자도 부족하고 할 일은 산더미인데, 나는 "동시에 많은 일을 하면 빠르겠지"라는 착각에 빠져 있었다. 버그 픽스하다가 새로운 기능 만들고, 그 사이에 고객 문의 답하고, 다시 원래 버그로 돌아오면 "어디까지 했더라?" 싶었다. 컨텍스트 스위칭 비용이 얼마나 큰지 몰랐던 것이다.
그러던 어느 날, 함께 일하던 개발자 한 명이 벽에 화이트보드를 붙이고 선 세 개를 그었다. "To Do", "Doing", "Done". 포스트잇 몇 장을 나눠주며 말했다. "우리가 지금 뭘 하고 있는지 보이게 합시다." 그리고 핵심 규칙 하나를 더했다. "Doing 칸에는 한 사람당 최대 2개까지만."
처음엔 답답했다. 급한 일이 터졌는데 Doing 칸이 꽉 찼다면? 그래도 규칙이었다. 하나를 끝내거나 누군가에게 넘기기 전에는 새 일을 시작할 수 없었다. 놀랍게도, 일주일 만에 완료 속도가 빨라지기 시작했다. 완료된 포스트잇이 Done 칸에 쌓여가는 게 눈에 보였다. 일의 흐름이 막히는 곳도 보였다. 테스트 칸에 포스트잇이 쌓이면 "아, 여기가 병목이구나" 싶어 리소스를 재배치했다.
이게 칸반(Kanban)이었다. 도요타 공장에서 시작해 소프트웨어 개발로 넘어온 시스템. 복잡해 보이는 프로젝트 관리 방법론이 아니라, 그냥 일의 흐름을 눈에 보이게 하고 병목을 뚫는 단순한 도구였다.
칸반(Kanban)은 일본어로 '간판'이라는 뜻이다. 1940년대 도요타 자동차 공장에서 만들어진 개념으로, 재고를 쌓지 않고 필요할 때 필요한 만큼만 생산하려는 JIT(Just-In-Time) 생산 방식의 핵심 도구였다. 창고에 부품이 바닥나면 '칸반 카드'를 공급자에게 보내 재주문하는 식이었다.
이 시스템의 핵심은 Pull(당김) 방식이다. Push(밀어넣기) 방식은 "이번 달에 차 1,000대 만들 거니까 부품 1,000대분 미리 준비해!"인데, Pull 방식은 "부품이 떨어졌으니 그때 주문해"다. Push는 재고가 쌓이고, Pull은 흐름이 자연스럽다.
소프트웨어 개발도 마찬가지다. "이번 분기에 기능 20개 만들자!"(Push)보다 "지금 고객이 원하는 기능 하나를 끝내고, 다음으로 넘어가자"(Pull)가 더 유연하다. 칸반은 2000년대 초 데이비드 J. 앤더슨(David J. Anderson)이 소프트웨어 개발에 적용하면서 애자일 방법론의 한 축으로 자리 잡았다.
칸반 보드는 단순하다. 화이트보드나 벽에 선을 몇 개 긋고, 각 구간을 '칸'으로 나눈다. 가장 기본적인 구성은 이렇다.
┌─────────────┬─────────────┬─────────────┬─────────────┬─────────────┐
│ Backlog │ To Do │ In Progress │ Review │ Done │
│ │ │ │ │ │
│ [Task A] │ [Task B] │ [Task C] │ [Task D] │ [Task E] │
│ [Task F] │ [Task G] │ [Task H] │ │ [Task I] │
│ [Task J] │ │ (WIP: 2/3) │ │ [Task K] │
│ ... │ │ │ │ │
└─────────────┴─────────────┴─────────────┴─────────────┴─────────────┘
일을 시작하면 카드를 오른쪽으로 옮긴다. 흐름이 눈에 보인다. "일이 어디서 막혀 있는지"도 보인다. Review 칸에 카드가 10개 쌓이면 "아, 리뷰가 병목이구나"가 보인다.
칸반을 처음 써본 건 스타트업 제품 출시 2주 전이었다. 할 일이 너무 많아서 노션에 리스트만 수십 개 만들어놨는데, 실제로 뭐가 진행 중인지 알 수 없었다. 칸반 보드를 벽에 그리고 포스트잇을 붙이니, "우리가 지금 30개를 동시에 하고 있구나. 그래서 하나도 안 끝나는구나"가 보였다.
칸반의 핵심은 WIP(Work In Progress) 제한이다. In Progress 칸에 들어갈 수 있는 카드 개수를 제한하는 것이다. 예를 들어 "WIP Limit: 3"이면, 3개의 작업이 진행 중일 때 새로운 작업을 시작할 수 없다. 하나를 끝내야 다음을 시작할 수 있다.
# Example: Kanban Board Config
columns:
- name: "To Do"
wip_limit: null
- name: "In Progress"
wip_limit: 3 # Maximum 3 tasks simultaneously
- name: "Review"
wip_limit: 2
- name: "Done"
wip_limit: null
왜 이렇게 해야 할까? 멀티태스킹은 느리다. 동시에 5개를 건드리면 컨텍스트 스위칭 비용이 커진다. 코드 짜다가 회의 가고, 돌아와서 "어디까지 했더라?" 하며 10분을 날린다. 심리학에서는 이걸 '전환 비용(Switching Cost)'이라 부른다.
WIP 제한은 이걸 막는다. 팀원이 3개의 작업을 하고 있는데, 상사가 "이것도 좀 해줘"라고 하면? "WIP 한계입니다. 뭘 멈출까요?"라고 물을 수 있다. 우선순위를 명확히 하게 만드는 장치다.
WIP 제한을 도입하면, 동시에 여러 작업을 하다가 아무것도 완료 못 하던 패턴에서 벗어나 하나씩 확실히 끝내면서 속도가 붙는다고 한다. 물이 흐르듯 일이 흐르게 된다.
칸반에서는 두 가지 시간 지표를 본다.
비유하자면, 식당에 비교할 수 있다. Lead Time은 손님이 주문한 순간부터 음식이 나오기까지의 시간이고, Cycle Time은 주방장이 실제로 요리를 시작한 순간부터 완성까지의 시간이다.
[Task 요청] ──────────────────> [완료]
↑ ↑
Lead Time (7일)
[작업 시작] ───────> [완료]
↑ ↑
Cycle Time (2일)
Lead Time이 길다면 대기 시간이 길다는 뜻이다. Backlog에 너무 오래 있거나, To Do에 쌓여 있다는 것. Cycle Time이 길다면 실제 작업 중에 지연이 생긴다는 뜻이다.
프로젝트 초기에 Lead Time이 길면(예: 평균 14일) 요청이 들어와도 실제 작업까지 오래 걸린다는 의미다. WIP 제한을 도입하고 병목을 해소하면 Lead Time이 절반 이상 줄어드는 개선 효과가 있다고 한다. 고객이 빨라진 걸 체감하게 된다.
칸반을 쓰다 보면 Cumulative Flow Diagram(CFD)을 그리게 된다. 시간 흐름에 따라 각 칸에 있는 작업의 개수를 누적해서 그래프로 그린 것이다.
작업 개수
▲
│ ┌─────────── Done
│ ┌───┘
│ ┌───┘ ┌─────── Review
│ ┌─┘ ┌─────┘
│┌────────┘ In Progress
│└──────────────────────
└──────────────────────────────> 시간
그래프의 두께가 각 칸에 쌓인 작업량이다. Review 구간이 계속 두꺼워지면 병목이 있다는 뜻. Done이 천천히 올라가면 전체 속도가 느리다는 뜻.
프로젝트에서 CFD를 주간 회의에 활용하면 흐름이 막히는 지점이 바로 보인다. 예를 들어 In Progress가 갑자기 두꺼워지면 "리뷰어가 부족해서 Review로 못 넘어가고 있구나"를 파악할 수 있다. 리뷰 시간을 더 배정하면 흐름이 다시 부드러워진다.
칸반과 스크럼(Scrum)을 헷갈리는 사람이 많다. 둘 다 애자일이지만, 접근 방식이 다르다.
| 칸반 | 스크럼 |
|---|---|
| 흐름 기반(Continuous Flow) | 스프린트 기반(Time-boxed Iterations) |
| WIP 제한 | 스프린트 용량 제한 |
| 역할 정의 없음 | Product Owner, Scrum Master, Dev Team |
| 회의 자유 | Daily Standup, Sprint Planning, Retrospective 고정 |
| 변경 자유로움 | 스프린트 중 변경 어려움 |
| 지속적 배포에 적합 | 정기 릴리스에 적합 |
칸반은 물처럼 흐른다. 버그 픽스, 유지보수, 지속적 배포에 적합하다. 급한 일이 생기면 우선순위를 바로 바꿀 수 있다.
스크럼은 박자가 있다. 2주 단위 스프린트로 일을 묶는다. 계획이 명확하고, 회고를 통해 개선할 수 있다.
프로젝트 초기에는 스크럼으로 기능을 개발하다가, 제품 출시 후 유지보수 단계로 넘어가면서 칸반으로 바꾸는 패턴이 많다. 버그가 터지면 바로 처리해야 하는데, "다음 스프린트에 넣자"는 말이 안 됐다. 칸반은 유연했다. 급한 일이 들어오면 To Do 맨 위에 놓고, WIP 제한 안에서 바로 처리할 수 있었다.
칸반 보드가 커지면 Swimlane(스윔레인)을 쓴다. 보드를 가로로 나눠서 작업 종류를 구분하는 것이다.
┌─────────────┬─────────────┬─────────────┬─────────────┐
│ To Do │ In Progress │ Review │ Done │
├─────────────┼─────────────┼─────────────┼─────────────┤ Feature (새 기능)
│ [Feature1] │ [Feature2] │ │ [Feature3] │
├─────────────┼─────────────┼─────────────┼─────────────┤ Bug (버그 수정)
│ [Bug1] │ │ [Bug2] │ [Bug3] │
├─────────────┼─────────────┼─────────────┼─────────────┤ Urgent (긴급)
│ │ [Urgent1] │ │ │
└─────────────┴─────────────┴─────────────┴─────────────┘
이렇게 하면 "긴급 작업이 얼마나 있는지", "버그 수정에 시간이 얼마나 걸리는지"가 보인다. "Feature", "Bug", "Chore"로 나누는 방식이 많이 쓰인다. Chore(잡일)가 계속 쌓이면 기술 부채가 쌓인다는 신호다.
칸반은 팀 도구만이 아니다. 혼자서도 쓸 수 있다. Personal Kanban이라 부른다. 나는 지금도 Notion에 개인 칸반 보드를 만들어 쓴다.
To Do:
- 블로그 글 쓰기
- 세금 신고
Doing (Limit: 2):
- 칸반 글 작성 중
- 고객 미팅 준비 중
Done:
- 운동
- 장보기
WIP를 2개로 제한하니, "오늘 이것도 하고 저것도 해야지"라는 욕심이 줄었다. 하나를 끝내고 다음으로 넘어가는 리듬이 생겼다.
개인 칸반의 핵심은 "내가 지금 뭘 하고 있는지 보이게 하는 것"이다. To Do 리스트는 끝이 없어 보이지만, 칸반은 진행 상태가 보인다. Done 칸에 카드가 쌓이면 성취감이 생긴다.
물리적인 화이트보드도 좋지만, 원격 팀이 많아지면서 디지털 칸반 도구가 필수가 됐다.
가장 단순하다. 보드, 리스트, 카드. 개인 프로젝트나 소규모 팀에 적합하다. WIP 제한을 강제하는 기능은 없지만, 파워업(플러그인)으로 추가할 수 있다.
엔터프라이즈급. 워크플로우 커스터마이징이 강력하다. 하지만 복잡하다. 설정만 일주일 걸릴 수 있다. 큰 조직, 복잡한 프로세스에 적합하다.
개발자 친화적. 키보드 단축키, 빠른 속도, 깔끔한 UI. GitHub 연동이 좋다. 스타트업에서 많이 쓴다.
GitHub 안에서 칸반을 쓸 수 있다. Issue와 PR을 카드로 만든다. 개발 워크플로우와 자연스럽게 연결된다.
# Example: GitHub Actions workflow for moving cards
name: Move to In Progress
on:
issues:
types: [assigned]
jobs:
move-card:
runs-on: ubuntu-latest
steps:
- name: Move issue to In Progress
uses: alex-page/github-project-automation-plus@v0.8.1
with:
project: My Kanban Board
column: In Progress
프로젝트에서 Linear를 쓰면 Issue를 만들고 상태를 바꿀 때 자동으로 칸반 보드가 업데이트된다. Slack 알림도 연동할 수 있다. "John이 'Login bug'를 In Progress로 옮겼습니다." 팀 전체가 누가 뭘 하는지 알 수 있다.
칸반 보드에서 카드를 Done으로 옮기려면 "완료"가 뭔지 정의해야 한다. 코드만 짜면 완료인가? 테스트도 해야 하는가? 배포까지 해야 하는가?
Definition of Done 예시는 이런 식이다.
### Definition of Done (DoD)
- [ ] 코드 작성 완료
- [ ] 유닛 테스트 작성 및 통과
- [ ] 코드 리뷰 승인
- [ ] QA 테스트 통과
- [ ] 프로덕션 배포
- [ ] 문서 업데이트 (필요 시)
이게 없으면 "완료"의 기준이 애매해진다. 개발자는 "코드 짰으니 완료"라고 하고, QA는 "테스트 안 했는데요?"라고 한다. DoD가 있으면 모두가 같은 기준으로 본다.
칸반의 핵심은 병목(Bottleneck)을 찾는 것이다. 물이 흐르다가 좁은 곳에서 막히듯, 일의 흐름도 어딘가에서 막힌다.
병목을 찾는 방법:
리뷰어가 한 명뿐인 프로젝트에서는 Review가 병목이 되기 쉽다. 그 사람이 바쁘면 카드가 Review 칸에 일주일씩 쌓인다. 해결책은 리뷰어를 늘리는 것이다. 팀원을 더 리뷰에 투입하면 흐름이 부드러워진다.
또 다른 병목은 "완벽주의"였다. 개발자 한 명이 코드를 계속 다듬느라 Done으로 안 옮겼다. "80%만 완성해도 넘어가자"는 규칙을 만들었다. 완벽하지 않아도 배포하고, 피드백 받아서 개선하자는 것. 속도가 다시 빨라졌다.
칸반은 지속적 배포(Continuous Delivery)와 궁합이 좋다. 스크럼처럼 2주마다 릴리스하는 게 아니라, 카드 하나가 Done이 되면 바로 배포하는 것이다.
칸반을 도입하면서 CI/CD 파이프라인을 함께 구축하면 배포 주기를 2주에서 하루 단위로 줄일 수 있다.
# Example: CI/CD Pipeline for Continuous Delivery
name: Deploy on Done
on:
project_card:
types: [moved]
jobs:
deploy:
if: github.event.project_card.column_name == 'Done'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Run tests
run: npm test
- name: Deploy to production
run: ./deploy.sh
카드가 Done 칸으로 옮겨지면 자동으로 테스트하고 배포됐다. 고객은 새로운 기능을 빠르게 받았고, 우리는 피드백을 빠르게 받았다. 빠른 피드백 루프가 제품을 더 빠르게 개선시켰다.
칸반은 복잡한 방법론이 아니다. 그냥 일의 흐름을 눈에 보이게 하고, 막히는 곳을 뚫는 것이다. 포스트잇 몇 장과 화이트보드면 시작할 수 있다. WIP 제한 하나만 지켜도 속도가 빨라진다.
첫 스타트업 제품 출시 때, 칸반이 없었다면 2주 안에 못 끝냈을 것이다. 칸반 보드를 벽에 그리고, 함께 일하는 사람들과 매일 아침 5분씩 보드 앞에 서서 "어제 뭐 했고, 오늘 뭐 할 건지, 막히는 게 있는지"를 말했다. 간단했다. 하지만 그 단순함이 투명성과 속도를 만들었다.
지금도 나는 개인 프로젝트에 칸반을 쓴다. Notion 보드에 "Writing", "Doing", "Done" 세 칸을 만들고, 글 주제를 카드로 만든다. Doing 칸에는 2개까지만. 하나씩 끝내고 Done 칸으로 옮기는 순간의 쾌감. 그게 나를 계속 움직이게 한다.
칸반은 마법이 아니다. 그냥 흐름을 보이게 하는 거울일 뿐이다. 하지만 그 거울을 보면, 막혔던 길이 보이고, 길이 보이면 뚫을 수 있다. 그게 칸반의 힘이다.