Feature Flag 는 왜 항상 그 자리에 남아 있나
플래그 청소가 미뤄지는 이유와 2026년 기준 실제 운영 경험 정리
우리는 플래그를 지운다고 했다
분기마다 같은 말을 했다. “다음 스프린트에 정리하자.” 막상 그 스프린트가 오면 플래그는 그대로고, 티켓은 backlog 최하단으로 밀린다.
왜 그런지 오래 생각했다. 답은 단순하다. 플래그를 지우는 일에는 인센티브가 없다. 지워도 서비스가 빨라지는 게 눈에 안 보인다. 누가 칭찬하지 않는다. 반면 잘못 지우면 바로 장애다. 불균형이 너무 크다.
실제로 2026년 기준 우리 코드베이스에서 isFeatureXEnabled 형태의 플래그를 grep 했더니 47개였다. 팀이 기억하는 건 7~8개. 나머지 39개는 “아마 켜져 있는 거 아닌가?” 수준. 일부는 생성한 엔지니어가 이미 팀을 떠났다.
청소 안 되는 구조적 이유
1. 오너십이 없다. 플래그를 만든 시점엔 오너가 명확하다. 그 기능을 만든 사람. 그런데 3개월 뒤 그 사람이 다른 팀으로 가면? 플래그는 고아가 된다. README 에 “누가 이 플래그 책임자” 를 적어둔 팀을 본 적이 별로 없다.
2. 플래그 목록이 흩어져 있다.
LaunchDarkly 쓰면 대시보드에, 환경변수로 관리하면 .env.example 에, 일부는 DB 테이블에. 어디에 얼마나 있는지 한눈에 볼 수 없다. 보이지 않으면 청소할 마음도 안 생긴다.
3. “혹시 몰라” 심리. 롤백 도구로 플래그를 쓴 경험이 한 번이라도 있으면, 지우는 게 무섭다. “이번 분기 안에 유사한 상황이 오면 다시 쓸 수도 있잖아요.” 이 말이 한 번이라도 나오면 그 플래그는 최소 6개월 더 산다.
4. 청소 비용이 생각보다 크다. 플래그 하나를 진짜로 지우려면: 코드에서 분기 제거 → 테스트 수정 → 플래그 관리 도구에서 삭제 → 배포 → 모니터링. 대충 반나절이다. 이걸 47개 하라고 하면 누구도 선뜻 안 한다.
그나마 효과 있었던 것
TTL 을 만든다. 플래그 생성 시점에 Jira 티켓 하나를 같이 만들고, due date 를 +90일 로 박는다. 자동으로 만들 수 없으면 수동으로라도. 이 티켓이 없으면 PR merge 를 막는 팀도 있다고 들었는데, 우리는 거기까진 못 했다. 그래도 due date 가 시각적으로 보이는 것만으로도 “아 이거 곧 정리해야 하는데” 가 한 번은 언급된다.
플래그에 이름 컨벤션을 건다. exp_ 접두어는 실험용, kill_ 접두어는 kill switch, legacy_ 는 구형 코드 분기. 이름만 봐도 아직 살아있어야 하는지 감이 온다. exp_ 인데 6개월 넘었으면 누군가가 알아서 물어본다.
분기 제거를 별도 PR 로 분리한다. 기능 완전 롤아웃 PR 과 플래그 cleanup PR 을 다른 날 한다. 한 번에 하면 리뷰어도 지쳐서 cleanup 부분을 대충 보게 된다. 나눠서 내면 cleanup PR 자체가 짧고 리뷰가 빠르다.
막상 해보면 플래그 청소는 규율 문제라기보다 가시성과 비용 문제다. 언제 죽어야 하는지 코드 옆에 쓰여 있고, 지우는 절차가 간단하면 사람들은 지운다. 지금 우리 팀에서 가장 오래 살아남은 플래그는 legacy_payment_v1_enabled 인데, 이걸 지우려면 결제 모듈 전체를 한 번 훑어야 한다는 사실이 알려진 순간부터 아무도 손을 안 댔다. 비용이 명확해지자 오히려 더 안 지웠다. 아이러니하게도 “이 플래그 지우는 데 반나절 걸린다” 는 문서를 써놓으니 그제서야 팀장이 일정을 잡아줬다.
다음 한 가지
다음 글에서 한 줄 확인: 이번 분기 안에 exp_ 접두어 플래그 중 90일 초과한 것 하나라도 실제로 지웠나.
🛒 이 글과 어울리는 추천 상품
위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.