「Feature Flag」とは何か。なぜ「Feature Flag」なのか

はじめに
ソフトウェア開発において「どうすれば新しい機能をより早く、より安全にユーザーへ届けられるか」という問いは、長年にわたり議論されてきました。開発手法やデリバリーパイプラインが進化するなかで、その答えの1つとして注目を集めているのが「Feature Flag」です。2024年の 「Gartner Hype Cycle for Agile & DevOps」において、Feature Management(機能管理)は“Slope of Enlightenment”に到達したと評価されました。つまり実験的な初期段階を越え、多くの組織で実用的価値が確認されつつあり、ソフトウェア開発における標準的なプラクティスのひとつへと歩みを進めています。
注目すべきは、Feature Flagが「システムの振る舞いを制御する仕組み」以上の役割を果たし始めていることです。レポートでは、新機能を制御するだけでなく、ユーザーからのフィードバックやメトリクスを用いたExperimentation(実験)との結びつきが強調されました。どの機能が顧客に真の価値をもたらすのかを素早く検証し、失敗した場合でもすぐに切り戻せる仕組みは、企業にとって競争力そのものといえます。
“Although feature flags were originally used to disable features that were not ready for deployment, they are now also used for experimentation, testing and progressive release. Features are being monitored and tested for value throughout their life cycle, creating feedback loops that aid in feature design.”
「Feature Flagは当初、未完成の機能をデプロイから除外するために使われていましたが、現在では実験やテスト、段階的なリリースにも活用されています。機能はライフサイクル全体を通じて価値が監視・検証され、その結果として得られるフィードバックループが機能設計を支えています。」
("Gartner, Hype Cycle for Agile and DevOps, 2024" より抜粋)
本連載は全5〜6回を予定しています。まずは本稿でFeature Flagの基本的な考え方とその価値を整理し、なぜいま必要とされているのかを確認します。続く回では、Feature Flagの内部の構成要素や代表的な分類を取り上げ、どのように設計・運用するのが望ましいかについて掘り下げます。さらに、デファクトスタンダードとなりつつある「OpenFeature」というFeature Flagのオープン仕様や、OpenFeature準拠の評価エンジンである 「flagd」を紹介し、エコシステムの広がりを示します。
また、中盤では「Zombie Flag」のような技術的負債や運用上の課題にも焦点を当て、導入に伴う落とし穴についても考察します。そして終盤ではGo言語を用いた具体的な実装例を取り上げ、実際にFeature Flagを利用した開発の流れをデモンストレーションします。
こうした流れを通じて、読者の皆さんが自分のプロダクトにFeature Flagをどう位置づけ、どう活用していくかを考える手がかりになれば幸いです。
本連載の対象読者は以下の通りです。
- 現在、プロダクト開発で Feature Flag を導入している or したい方
- 顧客に安全かつ高速に価値提供することを目指している方
Feature Flagとは何か
Feature Flagの定義は人や組織によってさまざまですが、本連載では一貫してFeature Flagを「変数によってシステムの振る舞いを制御する仕組み」として定義しましょう。特によく語られているのは「コードの変更をデプロイすることなく」という条件付きです。つまりソースコードとは別の離れた外部ストアにフラグ変数の値とフラグ変数の評価方法といった設定情報を有し、アプリケーションはその設定情報に従ってフラグの値を評価することでシステムの振る舞いを制御するということです。
Feature Flagは主に、条件文の単なる制御変数のように利用されます。まずは、実際にuse-new-algorithmというフラグを利用した、以下の Goコードを見てみましょう。
if client.BooleanValue(ctx, "use-new-algorithm") {
processWithNewAlgorithm(ctx)
} else {
processWithLegacyAlgorithm(ctx)
}
clientはFeature Flagのクライアントで、外部に存在する設定情報を取得するためのインターフェースだと考えてください。また、BooleanValueはクライアントのメソッドで、use-new-algorithmというフラグの値を何らかの評価方法で評価するためのメソッドです。今回は簡単のために、その評価方法は単に「外部ストアから現在の設定値を取ってくる」と考えましょう。より複雑な評価方法については次回で取り上げます。
use-new-algorithmの値がtrueと評価された場合はprocessWithNewAlgorithm、つまり新しいアルゴリズムで実行され、falseと評価された場合はprocessWithLegacyAlgorithm、つまり従来のアルゴリズムが実行されます。
先ほど述べた通り、use-new-algorithmは外部ストアに設定情報が存在します。開発チームのメンバーが外部ストアにおいて値をtrueからfalseに変更した際、以降アプリケーション内でフラグはfalseと評価されるようになり、従来のアルゴリズムが実行されるようになります。つまり、デプロイすることなく外部ストアに格納されている設定を変えるだけで、実行するアルゴリズムを切り替えることができるのです。
この「コードの変更をデプロイすることなく、変数によってシステムの振る舞いを制御する仕組み」というシンプルな定義を出発点にすると、そこから導かれるFeature Flagの実用的な可能性が見えてきます。
まず、もしアプリケーションの挙動を外部の設定だけで変えられるなら、ソースコードのデプロイと機能のリリースを切り離すことができます。これは「コードは本番環境に存在するが、機能はまだ公開しない」という状態を可能にし、リリースの柔軟性を大きく高めることに繋がります。また、この仕組みを環境ごとに設定すれば、本番環境では無効、開発環境では有効、といった切り替えも容易に行えるため、環境差分をブランチではなく変数で統一的に管理できるようになります。
さらに、変数による制御は単に環境単位にとどまりません。フラグの評価ロジックにユーザー属性や利用状況を反映させることで、よりきめ細かな機能の出し分けを実現できます。新機能を一部のユーザーには「隠す」ことも、逆に特定のユーザーに先行して「見せる」こともできます。公開範囲を徐々に広げたり、問題があれば即座に無効化することも同じ仕組みで実現できます。具体的な手法については次回で取り上げます。
ここまでをまとめると、Feature Flagは以下の特徴を持ちます。
- ソースコードのデプロイと機能のリリースを分離できる
- 機能を段階的にロールアウトできる
- 環境差分をブランチではなく、変数で管理できる
- ユーザー属性ごとに機能を出し分けできる
- 機能を即座に有効化したり、無効化に切り戻すことができる
このような特徴から、Feature Flagはトランクベース開発・キルスイッチ・A/Bテスト・カナリアリリースなど、様々なユースケースで利用されています。
なぜFeature Flagなのか
ソフトウェア開発において「機能を切り替える仕組み」は昔から存在していました。環境変数で挙動を変えたり、データベースに設定を保存して参照したりといった方法です。しかし、環境変数は環境単位の制御にとどまり、データベースはより柔軟に扱える一方で評価ロジックが分散しがちで、いずれも今日のプロダクト開発に不可欠なスピードや柔軟さを十分に支えきれないこともあります。
例えば、環境変数は環境全体の設定を一括で管理するには便利ですが、ユーザーごとに異なる挙動を制御したり、本番環境で段階的に公開範囲を広げるような使い方には不向きです。また、変更を即座に反映させるにはアプリケーションの再デプロイを伴う場合が多く、運用上の敏捷性も欠けています。データベースによる管理であればより細かい制御や即時反映は可能になりますが、そこにはスキーマ設計や評価ロジックの分散といった課題が伴い、履歴の保存や誰がいつ切り替えたかを追える監査ログ、切り替えがシステムに与える影響を可視化する可観測性といった要件を満たすには多大な追加開発が必要になります。
一方で、現代の開発現場ではユーザー体験を損なうことなく継続的に価値を届けることが強く求められています。新機能を少数のユーザーにだけ先行提供し、問題がなければ公開範囲を広げ、万一の際には即座に切り戻すこともあります。そしてユーザー属性ごとに機能を出し分け、A/Bテストを行いながら最適な選択肢を検証することもあります。こうした開発・運用のスタイルを支えるには、単なる設定管理ではなく機能のリリースそのものを制御するための専用の仕組みが必要になります。
Feature Flagが注目されるのは、まさにこの点にあります。デプロイとリリースを切り離し、環境ごとの差分やユーザーごとの条件を柔軟に扱いながら、安全で高速なプロダクト開発を実現したい。そのための基盤としてFeature Flagは欠かせない存在となっているのです。
主なユースケース
Feature Flagは「システムの挙動を変える仕組み」として汎用的に利用できますが、特に利用されるユースケースは以下の通りです。
機能を安全に公開する
新しい機能をリリースするときに、一度にすべてのユーザーに公開するのはリスクが高いものです。Feature Flagを使えばコード自体は本番環境にデプロイしつつ、機能をユーザーに見せるかどうかを制御できます。例えば、一部のユーザーにだけ段階的に公開したり、問題が起きたらすぐに無効化する「キルスイッチ」として使ったりできます。これにより、リリースに伴う不確実性を大幅に下げ、安全に新機能を届けることができます。なお、従来のCanary Releaseとは微妙に異なります。
Canary Releaseがデプロイ単位で一部ユーザーに新バージョンを配布するのに対し、Feature Flagは同一のデプロイ内で条件によって複数機能の有効・無効をそれぞれ独立して切り替えることができます。さらに、Canary ReleaseとFeature Flagでは責任の所在も異なります。Canary Releaseの場合はリリース戦略をコントロールする主体はインフラチームや運用チームが中心となります。一方でFeature Flagは各開発チーム自身が機能の公開範囲を柔軟に決められるため、プロダクト開発に直結した意思決定が可能になります。
ユーザー体験を比較・検証する
プロダクトの改善には「どのUI・どの機能がより良いのか」を実際のユーザーの行動から学ぶことが欠かせません。Feature Flagを使えば、A/Bテストのように異なるバージョン(≒機能)を同時に提供して比較できます。またユーザー属性や利用環境に応じて表示を切り替えれば、特定の条件下における機能の効果を検証することもできます。
トランクベース開発を実現する
「トランクベース開発」とは、開発チームが可能な限り短いサイクルでメインブランチ(=trunk)にコードを統合し続けるスタイルを指します。1日〜数日の単位で統合することが一般的で、長期間にわたって開発ブランチを保持しないことを原則とします。ブランチを長く持ち続けると統合時に大きなコンフリクトや品質劣化が発生しやすくなり、開発スピードを阻害するからです。そのため、トランクベース開発では未完成の機能でも早期に統合し、常にtrunkが最新かつ安定で、デプロイ可能な状態に保たれることが重視されます。
もっとも、未完成の機能を統合すると聞くと「ユーザーに中途半端な状態が見えてしまうのではないか」という懸念が生じます。そこで活用されるのがFeature Flagです。Feature Flagを利用すれば未完成の機能をtrunkに含めてもユーザーには非表示のまま保持でき、裏側で安全に開発を進められます。こうすることで開発者はtrunkに統合しながら段階的に実装を進められ、統合作業の負担を減らし、コードベースを常に最新に維持できます。
結果としてチームは小さな変更を高頻度で統合し、リスクを抑えつつ開発スピードを高めることができます。これは継続的インテグレーションや継続的デリバリーと自然に結びつき、モダンなソフトウェア開発を支える重要な考え方となっています。
これらのユースケースを通して注意していただきたいのは、Feature Flagはあくまで「アプリケーションの機能要件に対する制御として効果を発揮する」という点です。例えば、ユーザーごとのUIの出し分けやアルゴリズムの切り替えといった「軽量かつ柔軟な機能比較・機能検証」には非常に適しています。
一方で、インフラ構成の変更や非機能要件の検証には向いていません。例えば以下のようなケースです。
- ランタイムやライブラリの更新。Java 17 → Java 21 のような差分
- 大規模な構成変更。モノリスからマイクロサービスへの分割、新しいデータベース基盤への移行など
- 性能や安定性など非機能面での検証。レイテンシ・スループット・リソース消費の比較など
これらはアプリケーション内部のif文やフラグ切り替えで解決できる範囲を超えており、むしろService MeshやDeploymentのRolling Updateなどを用いたCanary Release、あるいはBlue/Green Deploymentの方が適しています。Feature Flagとこれらは競合関係ではなく、適材適所で補完し合う関係にあります。つまり「銀の弾丸はない」ということは指摘しておきます。
おわりに
本稿ではFeature Flagの定義とその基本的な仕組み、ユースケースについて紹介しました。Feature Flagを「変数によってシステムの振る舞いを制御する仕組み」と捉えることで、デプロイとリリースの分離、環境差分の柔軟な管理、そしてユーザーごとの出し分けが可能になることを確認しました。単なる条件分岐のように見えるものが、実際には現代のプロダクト開発を支える重要な基盤であることが理解できたと思います。
次回はFeature Flagの構成要素や分類を取り上げます。Toggle RouterやToggle Contextといった内部の仕組み、さらにRelease ToggleやExperiment Toggleなどの分類がどのように実際の現場で活用されているのかを掘り下げ、より実践的な理解を目指します。
【参考】- https://en.wikipedia.org/wiki/Feature_toggle
- https://martinfowler.com/articles/branching-patterns.html
- https://martinfowler.com/articles/feature-toggles.html
- https://launchdarkly.com/blog/git-branching-strategies-vs-trunk-based-development/
- https://launchdarkly.com/blog/whats-new-2024-agile-devops-gartner-hype-cycle/
- https://trunkbaseddevelopment.com/feature-flags/
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- フィーチャーフラグ管理の課題と宣言的集約管理、エコシステムの構築へ
- CI/CD Conference 2023、DMMのエンジニアが解説するCIを加速するトランクベースの開発とは
- 「Git」のブランチ戦略の基本とルールを学んで使いこなそう
- VLANトランクの設定を理解する[VLANとVLANトランクの分析]
- Oracle Cloud Hangout Cafe Season4 #3「CI/CD 最新事情」(2021年6月9日開催)
- VLANとVLANトランキングの設定と確認
- 「Git」によるスムーズなチーム開発を支えるルール作りと活用法を学ぼう
- DevOpsにおける開発者の振る舞いを理解しよう
- Kubernetesで安全にアプリケーションをデプロイするCDツール“Spinnaker”とは
- KFServingで機械学習モデルをサービング

