フィーチャーフラグ
フィーチャーフラグ
コードを残したまま機能のON/OFFを実行時に切り替える仕組み。デプロイとリリースを分離する。
概要
フィーチャーフラグ(フィーチャートグルとも呼ばれます)は、コードの中に「この機能を有効にするか」という分岐を仕込み、その ON/OFF をデプロイし直すことなく実行時に切り替えられるようにする仕組みです。新機能のコードは本番に配置済みだがフラグは OFF、準備が整った瞬間にフラグを ON にして公開する — つまり「コードを本番に置くこと(デプロイ)」と「機能をユーザーに見せること(リリース)」を別々のタイミングで行えるようになります。
この「デプロイとリリースの分離」が本質です。エンジニアは好きなタイミングで安全にデプロイし、プロダクトマネージャーはビジネス上最適なタイミングでリリースする。障害が起きても、デプロイのロールバックではなくフラグを OFF にするだけで機能を引っ込められる。さらに「全ユーザーの10%だけ ON」「社内ユーザーだけ ON」といった段階的な公開や A/B テストにも使えるため、単なる if 文の工夫を超えて、リリース戦略そのものを支えるインフラになっています。
なぜ生まれたか
背景にあるのは、ブランチ運用の苦しみです。かつては大きな機能を数週間かけて専用ブランチで開発し、完成してから main に統合するのが普通でした。しかし長生きしたブランチ同士の統合は衝突だらけの「マージ地獄」になり、CI/CD が目指す「小さく頻繁に統合する」という理想と真っ向から対立します。かといって未完成の機能を main に混ぜれば、次のデプロイで作りかけの画面がユーザーに見えてしまう。「統合は頻繁にしたい、公開はまだしたくない」— この矛盾を解いたのがフィーチャーフラグです。未完成コードをフラグで隠したまま main に統合すれば、ブランチを長生きさせずに済みます。全員が main に直接小さくコミットしていくトランクベース開発は、フィーチャーフラグがあって初めて現実的に回る開発スタイルです。
もう一つの背景は、リリースの意思決定を巻き戻し可能にしたいという運用上の要請です。デプロイと公開が一体だった時代、機能に問題があれば再デプロイという重い手続きでしか撤回できませんでした。フラグならスイッチ一つ、数秒で撤回できます。
詳細
仕組み — 分岐とフラグ管理の分離
コード側の実装は素朴で、if (flags.isEnabled("new-checkout", user)) のような分岐を書くだけです。仕組みの中心はむしろ、この判定の答えをコードの外から与えるフラグ管理側にあります。フラグの状態は設定ファイル・データベース・専用の管理サービス(LaunchDarkly や Unleash、OpenFeature 標準など)に置かれ、管理画面から変更すると、デプロイなしで全サーバの挙動が変わります。
判定は単純な真偽値にとどまりません。「ユーザーIDのハッシュ値で10%を選ぶ」「特定の組織・地域・プランのユーザーだけ ON」といったターゲティングルールを持てるのが実用上の要点で、同じユーザーには常に同じ結果が返るよう決定的に評価されます(毎回ランダムでは画面がリロードのたびに変わってしまいます)。これにより、カナリアリリースがインフラ層で行う段階的公開を、機能単位・アプリケーション層で実現できます。
フラグの4分類と使いどころ
フィーチャーフラグと一口に言っても寿命と役割はさまざまで、Pete Hodgson の整理では4種類に分けられます。未完成機能を隠して公開タイミングを制御する「リリーストグル」(寿命は数週間、リリース後に削除する)。A/B テストで2案をユーザー群に出し分け、メトリクスで効果を比較する「エクスペリメントトグル」(実験期間だけ生きる)。高負荷時に重い機能を落として本体を守る、いわば運用のスイッチである「オプストグル」(長寿命で、サーキットブレーカ的に使う)。有料プランにだけ機能を出すといった権限制御の「パーミッショントグル」(事実上恒久的)です。この分類が重要なのは、寿命と変更頻度が違うものを同じ仕組みで雑に扱うと後述の負債化を招くからです。
A/B テストの文脈では、フラグは実験基盤の中核になります。ユーザーを無作為に2群に分けて別の体験を与え、コンバージョン率などを統計的に比較する — 出し分けの機構はリリーストグルと同一で、違いは「効果測定とセットで運用されること」だけです。計測にはテストとはまた別の、行動ログの収集・分析の仕組みが必要になります。
負債化 — フラグの消し忘れという古典的な病
フィーチャーフラグ最大の落とし穴は、役目を終えたフラグがコードに残り続けることです。リリーストグルは全ユーザーに ON になった時点で用済みですが、削除は誰の緊急タスクでもないため放置されがちです。フラグが溜まると、分岐の組み合わせが爆発してテストすべき状態数が増え、「この分岐はもう通らないのか、誰も分からない」というデッドコードが蓄積します。実際、金融業界では、8年前の機能の死んだコードが残っていたことが一因で45分間に4.6億ドルを失った Knight Capital の事故が、フラグ管理の失敗例としてよく引き合いに出されます。
対策は運用の規律です。フラグ作成時に削除期限とオーナーを決める、管理サービスの「最終評価日時」で使われていないフラグを検出する、全公開から一定期間たったフラグの削除をスプリントの定常タスクに組み込む、といった仕組みで「作ったら消すまでがフラグ」を徹底します。また、フラグの評価結果はデバッグの重要な手がかりになるため、ログやトレースに「このリクエストはどのフラグがどう評価されたか」を記録しておくと、「一部のユーザーだけ挙動が違う」という調査が格段に楽になります。
デプロイ戦略の中での位置づけ
ブルーグリーンデプロイやカナリアリリースがバージョン全体をインフラ層で切り替えるのに対し、フィーチャーフラグは個々の機能をコード内で切り替えます。粒度が細かいぶん制御は柔軟ですが、分岐がコードに増える複雑さのコストを払います。実務では対立ではなく併用が基本です。デプロイの安全性はカナリアで、機能公開のタイミングと対象はフラグで制御する、という二段構えが、リリース頻度と安全性を両立させる現代的な構成です。