Files
2nd/10_Wiki/Topics/DevOps_and_Security/Feature-Flags.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

4.8 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-feature-flags Feature Flags 10_Wiki/Topics verified self
Feature Toggles
Feature Switches
Feature Gates
none A 0.9 applied
devops
deployment
experimentation
release-engineering
2026-05-10 pending
language framework
TypeScript/Go LaunchDarkly/Unleash/OpenFeature

Feature Flags

매 한 줄

"매 deploy 와 release 를 매 분리하는 runtime conditional". Pete Hodgson 의 매 4-axis taxonomy (release/experiment/ops/permission) 가 매 baseline. 매 modern stack — OpenFeature spec + provider (LaunchDarkly, Unleash, ConfigCat, Statsig) — 매 progressive delivery, A/B test, kill switch 의 매 통합 layer.

매 핵심

매 4 종류 (Hodgson)

  • Release toggle: dark launch, gradual rollout (short-lived).
  • Experiment toggle: A/B/n test (medium-lived).
  • Ops toggle: kill switch, circuit breaker (medium-lived).
  • Permission toggle: per-user/tenant entitlement (long-lived).

매 axis

  • Lifetime: hours ↔ years.
  • Dynamism: build-time → runtime → request-time.
  • Scope: global → user → request.

매 응용

  1. Trunk-based development + dark launch.
  2. Canary / progressive rollout (1% → 100%).
  3. Kill switch (incident mitigation).
  4. A/B testing & holdout group.
  5. Tier-based feature gating (free/pro/enterprise).

💻 패턴

OpenFeature SDK (vendor-neutral)

import { OpenFeature } from '@openfeature/server-sdk';
import { LaunchDarklyProvider } from '@openfeature/launchdarkly-server-provider';

await OpenFeature.setProviderAndWait(new LaunchDarklyProvider(SDK_KEY));
const client = OpenFeature.getClient();

const showNew = await client.getBooleanValue('new-checkout', false, {
  targetingKey: user.id,
  email: user.email,
  plan: user.plan,
});
return showNew ? renderNewCheckout() : renderOldCheckout();

Percentage rollout (deterministic hash)

import "hash/fnv"
func rollout(flagKey, userID string, percent int) bool {
    h := fnv.New32a()
    h.Write([]byte(flagKey + ":" + userID))
    return int(h.Sum32()%100) < percent
}
// Same user → same bucket across calls (sticky).

Kill switch (ops toggle)

async function fetchRecommendations(userId: string) {
  if (await flags.getBooleanValue('reco-kill-switch', false)) {
    return []; // disable the feature instantly during incident
  }
  return recoService.fetch(userId);
}

Multivariate experiment

const variant = await client.getStringValue('checkout-variant', 'control', ctx);
switch (variant) {
  case 'one-click': return <OneClickCheckout />;
  case 'wallet':    return <WalletCheckout />;
  default:          return <StandardCheckout />;
}
metrics.track('checkout_view', { variant, userId });

Local override (dev/test)

if (process.env.NODE_ENV === 'development') {
  OpenFeature.setProvider(new InMemoryProvider({
    'new-checkout': { defaultVariant: 'on', variants: { on: true, off: false } },
  }));
}

Flag cleanup (technical debt)

# Find old flags
rg "getBooleanValue\\('old-checkout'" --type ts
# Provider audit: list flags > 90 days old, no recent eval, 100% rollout → delete.

매 결정 기준

상황 Approach
Dark launch / gradual Release toggle, percentage rollout
Hypothesis test Experiment toggle + analytics
Incident mitigation Ops toggle (always available)
Tier / paid features Permission toggle (long-lived)
Build-time only Compile flag (no runtime cost)

기본값: OpenFeature SDK + managed provider (LaunchDarkly/Unleash). Kill switch 모든 critical path 에 매.

🔗 Graph

🤖 LLM 활용

언제: Release strategy 설계, incident playbook, experiment platform 평가. 언제 X: Static config — env var / config file 충분.

안티패턴

  • Flag debt: 100% rolled-out flag 를 매 안 지움 → cyclomatic complexity 폭발.
  • Nested flags: A&&B&&C — 매 test space 매 explosion.
  • Flag in hot loop: per-request eval 의 매 latency — cache locally.
  • No fallback: provider 다운 시 feature 깨짐 — default + cached value.
  • Flag = config 오용: 진짜 config 는 매 config service 로.
  • No analytics linkage: experiment 인데 evaluation 안 records.

🧪 검증 / 중복

  • Verified (martinfowler.com Feature Toggles, OpenFeature spec, LaunchDarkly docs).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — 4-axis taxonomy + OpenFeature/percentage/kill-switch 패턴