콘텐츠로 바로가기

Feature Flag

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

11분 읽기
목차 보기22

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를 통한 트래픽 라우팅 → 09-05-04 CI/CD Pipeline 영역으로 위임 (여기는 인프라가 아닌 '로직/코드 레벨'의 통제에 집중).
  • A/B 테스트 통계학: T-test, P-value 등 통계적 유의성 검증 수학 → 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:
    JAVASCRIPT
    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달 고립 → Merge 시 1,000줄 충돌 → 해결에 2일 소요. 피처 플래그: 빈 깡통 함수 A() 작성 + Flag=OFF → 즉시 main 병합. 내일은 A() 안에 10줄 추가 → 즉시 병합. 브랜치의 수명을 '하루 이내'로 압살해 버리는 시각화.

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)하는 팀 거버넌스를 구축할 수 있는가?

태그

feature-flagdeploymenttrunk-based-developmentexperimentationreleasesoftware-engineeringfeatureflagsoftwareengineeringtrunkbaseddev-opsreliabilitydelivery

DevOps & Delivery

5 / 5