콘텐츠로 바로가기

Feature Flag

코드 배포와 기능 활성화를 분리하는 기법. 런타임에 기능을 켜고 끌 수 있어 안전한 배포와 점진적 롤아웃을 가능하게 함. 플래그가 쌓이면 코드베이스가 복잡해짐. 출시 완료된 Release Toggle은 반드시 제거. "플래그 청소 티켓"을 배포 직후 바로 생성하는...

Article
M

Me

hyunyoun's Blog

software-engineering-devopssoftware-engineeringdev-opsreliabilityfeature-flagdeliverylearningdeployment11 min read

1. Overview

피처 플래그 물리법칙(Feature Flag & Toggle)은 "코드를 배포하는 것(Deploy)"과 "기능을 고객에게 노출하는 것(Release)"을 영원히 분리해 버리는, 코드 레벨의 통제권 역전이자 if문 하나로 수천만 명의 트래픽을 제어하는 다이나믹 스위칭 역학을 해부합니다.

학습자는 미완성된 기능 때문에 브랜치를 feature/A로 파놓고 두 달 동안 합치지 못해 썩어가는 브랜치 지옥을 뜯어보고, 미완성 코드를 당당하게 운영 서버(main)에 합치면서도 스위치를 꺼(OFF) 고객에게 숨기는 **트렁크 기반 개발(Trunk-based Development)**을 장악합니다. 나아가 코드 재배포 없이 실시간으로 기능을 1% 유저에게만 켜주는 **카나리아 릴리즈(Canary Release)**와, 피처 플래그가 쌓여서 생기는 기술 부채(Technical Debt)의 관리 파이프라인 역량을 확보합니다.

2. Scope & Boundaries

In-Scope

  • Deploy vs Release: 인프라 배포와 비즈니스 기능 오픈의 완벽한 디커플링(Decoupling).
  • Toggle Types: Release Toggles, Experiment Toggles (A/B Test), Ops Toggles, Permission Toggles.
  • Trunk-based Development: 롱 리브드 브랜치(Long-lived branch) 폐기와 매일 10번 병합하는 극강의 CI 전략.
  • Lifecycle Management: 다 쓴 플래그(if문)를 지우지 않으면 발생하는 스파게티 코드와 부채 탕감 거버넌스.

Out-of-Scope

  • Canary Deployment 인프라 레벨 통제: K8s Istio를 통한 트래픽 라우팅 \rightarrow 09-05-04 CI/CD Pipeline 영역으로 위임 (여기는 인프라가 아닌 '로직/코드 레벨'의 통제에 집중).
  • A/B 테스트 통계학: T-test, P-value 등 통계적 유의성 검증 수학 \rightarrow 01. Data & Analytics 모듈로 분리.

Boundaries

  • Canary Deployment vs Feature Flag: 두 개의 서버 V1과 V2를 띄우고 로드밸런서가 트래픽을 10%만 V2(신규)로 찢어 보내면 '카나리아 배포(인프라)'입니다. 반면 서버는 V1 하나만 떠 있는데, 소스코드 안의 if(enable_new_feature) 조건을 유저의 10%에게만 true로 열어주면 '피처 플래그(코드)'입니다. 인프라를 늘릴 것인가, 로직 스위치를 달 것인가의 경계를 명확히 긋습니다.

3. Counterexample

  • 브랜치의 부패 (Feature Branch Hell): 두 달짜리 거대한 결제 개편 기능을 만들기 위해 feature/payment_v2 브랜치를 땄습니다. 두 달 뒤, 메인 브랜치는 다른 팀원들에 의해 1,000번이나 커밋(변경)되었습니다. 이제 결제 브랜치를 메인에 합치려니 충돌(Conflict)이 500군데 발생합니다. 기능을 숨길 스위치가 없어서, 완벽히 다 만들 때까지 합치지도 못하고 썩혀둔 구시대의 참사입니다.
  • Knight Capital 4,500억 원 증발 (Dead Code): 2012년 나이트 캐피탈은 옛날에 만들어두고 안 쓰는 죽은 코드(Dead Code) 스위치를 실수로 켜(ON)버렸습니다. 코드는 미친 듯이 시장에 고가 매수/저가 매도 주문을 난사했고, 회사는 45분 만에 4억 4천만 달러(약 4,500억 원)를 날리고 파산했습니다. 피처 플래그(스위치)를 쓴 뒤 청소하지 않고 방치한 기술 부채가 불러온 역사상 최악의 소프트웨어 파국입니다.

4. Prerequisites

  • 버전 관리 시스템 (Basic): Git, Branching, Merge Conflict. (09-05 DevOps Basic)
  • CI/CD 파이프라인 (Basic): 자동화된 빌드와 배포의 차이. (09-05-04 CI/CD)

5. Learning Map

Sequence Core Cluster Objective & Description Evidence (BoK)
1 Deploy != Release 서버에 코드를 올리는 행위(Deploy)와 고객이 새 기능을 보는 행위(Release)의 연결고리를 도끼로 끊어내는 분리의 마법을 쥡니다. P1
2 Trunk-based Development "아직 개발 중이라 못 합쳐요"라는 변명을 부수고, 뼈대만 있는 미완성 코드라도 스위치를 끈 채 무조건 매일 main에 합치는 권력을 뜯어봅니다. P5
3 The 4 Dimensions of Toggles 신기능 출시용, A/B 테스트용, 서버 과부하 킬스위치용, VIP 전용 스위치라는 4가지 토글의 물리적 수명과 역할을 장악합니다. Industry
4 The Cleanup Governance 쓰임이 다한 수백 개의 if문을 방치하다 4,500억 원이 날아간 나이트 캐피탈의 저주를 막기 위한 기술 부채 청소(Cleanup) 체계를 확보합니다. Industry

6. Learning Topics

Basic

Core Topic 01: 배포와 릴리즈의 분리 (Deploy != Release)

  • Why to Learn: "이번 주 금요일 밤 12시에 배포하고 즉시 오픈합시다"라는 낡고 위험한 빅뱅 릴리즈를 버리고, 수요일 대낮에 미리 배포해두고 금요일 밤에는 버튼만 딸깍 누르는 심리적 평화를 얻기 위함입니다.
  • What to Learn:
    • Concepts: Deployment (배포), Release (출시), Feature Flag / Toggle, Decoupling.
    • Skills: 애플리케이션 코드 곳곳에 if (feature_flag.is_on('NEW_PAYMENT')) { 신규로직 } else { 기존로직 }을 감싸, 배포를 하더라도 플래그가 OFF면 고객은 100% 기존 로직만 타도록 통제하기.
  • How to Learn:
    • 1단계: 강결합의 공포: 전통적으로 코드 배포 = 기능 오픈입니다. 서버가 켜지는 순간 신규 기능이 세상에 노출됩니다. 에러가 나면 코드 수정, 빌드, 재배포까지 30분이 걸립니다. 고객은 30분 동안 마비됩니다.
    • 2단계: 절단 (Decoupling): 피처 플래그를 달면 배포와 오픈이 완벽히 분리됩니다. 배포는 평일 낮 한가할 때 미리 100번이고 해둡니다. 스위치가 꺼져있으니 고객은 모릅니다.
    • 3단계: 딸깍 (Instant Release): 약속한 론칭 시각이 되면, 개발자가 코드를 재배포하는 게 아니라 기획자가 대시보드(LaunchDarkly 등)에서 스위치를 'ON'으로 켭니다. 1밀리초 만에 신규 로직이 활성화됩니다. 문제가 생기면 즉시 'OFF'로 꺼서 1밀리초 만에 롤백하는 극강의 방어술을 해부합니다.
  • Implement: 피처 플래그 분기 코드 모사. Action:
    CODE
    if (flagService.isEnabled('v2-ui')) {
      return renderNewUI(); // 스위치 ON (1초 만에 롤백 가능)
    } else {
      return renderOldUI(); // 스위치 OFF (안전지대)
    }
    인프라(배포)의 영역이 비즈니스(출시)의 영역으로 우아하게 넘어가는 권력 이동 렌더링.

Core Topic 02: 미완성 코드의 합병 (Trunk-based Development)

  • Why to Learn: 브랜치를 수십 개씩 파놓고 3달 뒤에 합치려다 충돌(Merge Conflict)로 밤을 새우는 참사를 막고, 모든 팀원이 매일 오직 main 브랜치 하나만 바라보며 개발하는 극한의 애자일을 달성하기 위함입니다.
  • What to Learn:
    • Concepts: Trunk-based Development (트렁크 기반 개발), Feature Branching Hell, CI (지속적 통합), Dark Launch.
    • Skills: 미완성된 껍데기 함수(결제 버튼 등)를 만들고 피처 플래그로 완전히 숨긴(Dark Launch) 다음, 당당하게 main 브랜치에 하루에 10번씩 병합(Merge)하여 충돌을 원천 차단하기.
  • How to Learn:
    • 1단계: 격리의 모순: 남의 코드와 섞이는 게 두려워 브랜치를 오래 유지(Long-lived)할수록, 나중에 합칠 때 발생하는 고통은 제곱으로 커집니다.
    • 2단계: 피처 플래그의 보호막: "미완성된 코드는 실서버에 나가면 안 된다"는 상식을 뒤집습니다. 스위치(Flag)로 꺼두면 그 코드는 '죽은 코드'로 취급되어 실행되지 않습니다.
    • 3단계: 트렁크 기반 개발: 이제 모든 개발자는 하루 단위로 미완성 코드를 main(트렁크)에 때려 박습니다. 다른 팀원들이 짠 코드가 내 로컬에 실시간으로 반영되므로 '병합 지옥'이 수학적으로 소멸합니다. 완성되지 않은 기능을 운영 서버에 숨긴 채 점진적으로 개발해 나가는 경이로운 CI/CD 가속술을 뜯어봅니다.
  • Implement: 롱 리브드 브랜치 vs 트렁크 기반 개발 렌더링. 구시대: feature/A 1달 고립 \rightarrow Merge 시 1,000줄 충돌 \rightarrow 해결에 2일 소요. 피처 플래그: 빈 깡통 함수 A() 작성 + Flag=OFF \rightarrow 즉시 main 병합. 내일은 A() 안에 10줄 추가 \rightarrow 즉시 병합. 브랜치의 수명을 '하루 이내'로 압살해 버리는 시각화.

Practical

Core Topic 03: 4차원의 스위치 (The 4 Dimensions of Toggles)

  • Why to Learn: 스위치라고 해서 다 같은 스위치가 아닙니다. 2주 뒤에 지울 스위치(Release)와 평생 안고 가야 할 킬스위치(Ops)를 구별하여 잘못된 관리를 막기 위함입니다.
  • What to Learn:
    • Concepts: Release Toggles (출시 스위치), Experiment Toggles (A/B 테스트), Ops Toggles (운영 킬스위치), Permission Toggles (권한 제어).
    • Skills: "장바구니 로직 개편"은 Release Toggle로 짧게 쓰고 버리며, "결제 시스템 장애 시 외부 PG사 셧다운"은 Ops Toggle로 시스템 깊숙이 평생 유지하는 매트릭스 분기하기.
  • How to Learn:
    • 1단계: Release Toggles: 기능 출시용. 며칠 뒤 100% 유저에게 기능이 완전히 켜지면 수명이 다합니다. 즉시 코드에서 if문을 지워버려야(Cleanup) 합니다.
    • 2단계: Experiment Toggles: A/B 테스트용. 유저 50%는 A버튼, 50%는 B버튼을 보여줍니다. 데이터 분석이 끝나고 위너(Winner)가 결정되면 역시 수명이 다하므로 지워야 합니다.
    • 3단계: Ops Toggles: 블랙프라이데이 때 트래픽이 폭주해서 서버가 터질 것 같으면, "추천 상품 연산 로직"만 일시적으로 꺼버리는(Kill Switch) 생존용 토글입니다. 이건 평생 유지됩니다.
    • 4단계: Permission Toggles: VIP 유저나 관리자에게만 특정 프리미엄 기능을 열어줍니다. 유저의 속성(Attribute)에 따라 동작하며 역시 영구적으로 유지됩니다. 토글의 수명(Lifetime)과 동적 성질에 따른 완벽한 분류법을 해부합니다.
  • Implement: 킬스위치(Ops Toggle) 방어 메커니즘 도출. 위기 상황: 결제 서버 트래픽 10배 폭증 (CPU 99%). Action: is_enabled('RECOMMENDATION_ENGINE') 스위치를 대시보드에서 긴급 OFF. 결과: 홈 화면에서 추천 상품을 그리기 위한 무거운 DB 쿼리들이 즉각 생략됨. 핵심 로직(결제)을 살리기 위해 부가 기능의 숨통을 코딩 없이 끊어버리는 오퍼레이션 시각화.

Advanced

Core Topic 04: 스위치 청소 거버넌스 (The Cleanup Governance)

  • Why to Learn: 피처 플래그를 편하다고 막 쓰다가, 코드 안에 3년 전 if문 100개가 누적되어 아무도 건드릴 수 없는 썩은 기술 부채로 전락해 4,500억 원(나이트 캐피탈)을 날려먹는 걸 막기 위함입니다.
  • What to Learn:
    • Concepts: Technical Debt (기술 부채), Stale Flags, Cleanup Lifecycle, Feature Flag Management System.
    • Skills: 기능이 100% 릴리즈 된 지 2주가 지난 '좀비(Stale) 플래그'를 자동으로 찾아내어 슬랙(Slack)으로 삭제 경고를 날리고, 코드에서 else 문구를 제거하는 리팩터링 룰 강제하기.
  • How to Learn:
    • 1단계: 스파게티의 탄생: 플래그를 달면 필연적으로 if (신규) else (기존) 구조가 생깁니다. 분기가 2개(2차원)로 늘어납니다. 만약 플래그가 3개 겹치면? 2^3 = 8차원의 복잡도가 생겨 테스트가 불가능해집니다.
    • 2단계: 부채의 이자: 100% 릴리즈되어 더 이상 'OFF'로 돌릴 일이 없는 플래그는 즉시 삭제해야 합니다. 방치하면 나중에 신입 개발자가 "어? 이 조건문은 뭐지?" 하며 건드렸다가 대형 장애가 터집니다.
    • 3단계: 자동화된 청소 루프: 지라(Jira) 티켓에 "플래그 청소" 하위 테스크를 의무적으로 강제합니다. 코드를 짤 때 아예 플래그 만료일(Expiration Date)을 설정하고, 기한이 지나면 빌드(CI)를 뻗게 만들어 개발자가 억지로라도 코드를 지우게 만드는 냉혹한 기술 부채 탕감 시스템을 뜯어봅니다.
  • Implement: 플래그 탕감 라이프사이클 시각화. Day 1: 브랜치 병합 (Flag = 0% 노출). Day 7: 런칭 완료 (Flag = 100% 노출). Day 21 (경고): 런칭 후 2주 경과. CI 시스템이 "Stale Flag Detected" 슬랙 알람 발송. Day 22 (청소): 개발자가 if 분기를 날리고 신규 로직(True)만 남긴 후 커밋. 복잡도가 다시 1차원으로 수렴하는 클린 아키텍처 렌더링.

7. Terminology

Term (EN / ko, abbr) 1문장 정의 단계(기본/권장/실무/심화) 역할/맥락 관련 개념 유사/대비/함께 사용 오해 포인트 Evidence(Primary/Secondary/Industry) Flags(core)
Feature Flag / Toggle (피처 플래그/토글) 소스 코드 안에 숨겨진 if/else 스위치로, 서버 재배포 없이 실시간으로 기능을 켜거나 꺼서 유저에게 노출되는 로직을 통제하는 다이나믹 스위칭 기술입니다. 기본 배포와 출시의 완벽한 분리(Decoupling) A/B Testing / Dark Launch Canary Deployment (카나리아 배포) 카나리아가 "서버 100대 중 1대로 트래픽을 보냄(인프라 통제)"이라면, 피처 플래그는 "서버 안의 특정 로직을 1% 유저에게만 실행시킴(로직 통제)"임 P1:CS2023 core
Trunk-based Development (트렁크 기반 개발) 두 달씩 고립되는 브랜치(Feature Branch)를 버리고, 모든 개발자가 미완성된 코드라도 피처 플래그로 숨긴 채 매일 수십 번씩 메인(main/트렁크) 브랜치에 때려 박는 초고속 통합 전략입니다. 권장 병합 지옥(Merge Hell)의 궁극적 해결 CI (지속적 통합) / Feature Branch Git Flow (깃 플로우) develop, release 등 복잡한 브랜치를 두는 Git Flow와는 정반대의 철학. "브랜치는 죄악이다, 무조건 트렁크(메인)에 즉시 쑤셔 넣어라"가 트렁크 기반 개발임 P5:SFIA core
Dark Launch (다크 론칭) 기능을 100% 다 만들고 세상에 빵! 터뜨리는 대신, 피처 플래그를 꺼둔 상태로 프로덕션에 몰래 배포해 두고 특정 내부 테스터나 QA만 켜서 확인해 보는 은밀한 배포술입니다. 실무 프로덕션 환경에서의 안전한 테스트 보장 Staging Environment / Release Toggle A/B Testing A/B 테스트는 유저 반응(전환율 등)을 '통계적'으로 보려는 것이고, 다크 론치는 '기능이 버그 없이 잘 도는지' 프로덕션 인프라에서 안전하게 훔쳐보는 것임 Industry core
Stale Flag / Technical Debt (방치된 플래그/기술 부채) 100% 릴리즈되어 더 이상 쓸모가 없어졌음에도 코드 속에 if-else 블록으로 방치되어, 스파게티 코드를 유발하고 치명적 버그(나이트 캐피탈 사태)를 낳는 시한폭탄입니다. 심화 토글 생명주기 관리 및 부채 탕감 Cleanup Lifecycle / Refactoring Ops Toggle (운영 킬스위치) 킬스위치(Ops)나 권한 스위치(Permission)는 수명이 영구적이므로 놔둬도 되지만, 신기능 출시용(Release) 스위치를 방치하는 건 집 안에 쓰레기봉투를 쌓아두는 것과 같음 Industry core

8. References

Primary

  • [P1] CS2023 - Software Engineering (SE) - Software Release and Deployment (Feature toggles, CI/CD)
  • [P5] SFIA - Programming/software development (PROG) - Feature flag implementation

Secondary

  • [Continuous Delivery] Jez Humble - Trunk-based development and branching strategies
  • [MartinFowler.com] - FeatureToggles (by Pete Hodgson)

Industry

  • [LaunchDarkly Blog] - The Ultimate Guide to Feature Flags
  • [GitLab Docs] - Feature flags and Trunk-based development

9. Final Checklist

Primary

  • 서버에 코드를 올리는 "배포(Deployment)"와 고객에게 새로운 기능을 노출하는 "출시(Release)"의 개념을 명확히 분리하고, 피처 플래그가 이 둘의 강결합을 어떻게 도끼로 끊어내는지 논증할 수 있는가?
  • 미완성된 기능 때문에 브랜치를 장기간 격리했다가 병합 지옥(Merge Hell)을 겪는 대신, 미완성 코드를 플래그로 감춰 매일 main 브랜치에 합치는 '트렁크 기반 개발(Trunk-based Development)'의 속도전 원리를 설명할 수 있는가?

Secondary

  • 신기능을 런칭하고 곧바로 지워버려야 하는 '출시 토글(Release Toggle)'과, 블랙프라이데이 트래픽 폭주 시 일시적으로 부가 기능을 꺼버리기 위해 영구히 유지해야 하는 '운영 토글(Ops Toggle)'의 생명주기(Lifecycle) 차이를 분기할 수 있는가?
  • 카나리아 배포(Canary Deployment)가 로드밸런서를 통한 '인프라/서버 레벨'의 트래픽 라우팅 통제인 반면, 피처 플래그(Feature Flag)를 활용한 1% 점진적 롤아웃이 '로직/코드 레벨'의 유저 세그멘테이션 통제임을 명확히 구분하여 설계할 수 있는가?

Industry

  • 2012년 4,500억 원의 손실을 낸 나이트 캐피탈(Knight Capital) 사태를 예시로 들어, 쓰임이 다한 오래된 피처 플래그(Stale Flag)를 삭제(Cleanup)하지 않고 방치했을 때 폭증하는 코드의 다차원적 복잡도와 기술 부채의 파국을 경고할 수 있는가?
  • 100% 롤아웃된 피처 플래그의 삭제를 개발자의 양심에 맡기지 않고, 지라(Jira) 티켓과 CI/CD 파이프라인에 만료일(Expiration Date) 알람을 연동하여 강제적으로 리팩터링 및 else 블록을 탕감(Cleanup)하는 팀 거버넌스를 구축할 수 있는가?

DevOps & Delivery

5 / 5