フィーチャーフラグとは? 個人開発者向けの平易な解説
要約
フィーチャーフラグ(機能フラグ、フィーチャートグル)とは、設定の値をコードの外で管理する条件分岐のことです。デプロイし直さずに機能を切り替えられるため、「デプロイ」と「リリース」を切り離せます。未完成のコードを毎日マージする、1%のユーザーに段階的に公開する、問題が起きたら即座に止める、といったことが可能になります。ただし、フラグは必ずコードパスを増やし、ロールアウト後に削除しなければなりません。個人開発なら、初日からベンダーを入れる必要はほとんどありません。
フィーチャーフラグとは、設定の値をコードの外に置いた if 文のことです。新しいコードは最初はオフの状態でデプロイし、後から設定ファイル、データベースの1行、フラグ管理サービスのいずれかの値を変えるだけで有効にできます。デプロイし直す必要はありません。この仕組みが、コードを出すことと機能を公開することを切り離します。だからフラグは、最も安く手に入るロールバック手段なのです。
後半の内容は、私が身をもって学んだことです。最初のフラグは環境変数に入れた真偽値で、金曜の夜にオンにしました。そのあと11か月、存在を忘れていました。何も壊れませんでした。まさにそれが問題で、この後詳しく扱います。
コードの中のフィーチャーフラグはどんな形か
思っているより小さいものです。ダッシュボードを取り払えば、フラグは参照と分岐だけです。
const flags = { newCheckout: false };
if (flags.newCheckout) {
return renderNewCheckout(user);
}
return renderOldCheckout(user);残りは、フラグの値がどこから来るのか、そして誰が変えられるのか、という問いです。ファイルに書いた定数は、変えるためにデプロイが必要なので、フラグの意味がありません。環境変数は再起動で反映されます。データベースの行は数秒で変わります。ホスト型サービスも数秒で変わり、さらにユーザー単位のターゲティング、管理画面、変更履歴が付いてきます。
ここで引っかかるのは実務的な面です。コードは単純ですが、ライフサイクルは単純ではありません。本番に分岐が2つあるとは、テストすべき動作が2つ、夜中の2時にデバッグすべき経路が2つあるということで、そのうち1つは腐っていく運命にあります。

フィーチャーフラグの4つの種類と、最初に必要なもの
Martin Fowler の feature toggles の分類 は、今も種類を整理する最も明快な方法です。役立つ軸は、それぞれどれくらい生かしておくべきかです。
リリースフラグ: 未完成または危険な作業を隠します。一時的なもので、1〜2週間で削除します。最初に必要になるのはこれです。
運用フラグ(キルスイッチ): 重く壊れやすい機能を包み、負荷がかかったときにデプロイなしで止められるようにします。大半は短命ですが、一部は永続して問題ありません。
実験フラグ: A/Bテストのためにユーザーをコホートに分けます。統計的に意味のある結果が出るまで生かし、実トラフィックが必要です。
権限フラグ: プランやアカウントで機能を制限します。Proプランやベータグループなどです。数年続くこともありますが、その時点ではもうフラグというより権利(エンタイトルメント)なので、適切なデータモデルを設計すべきです。
40人しかユーザーがいない個人開発者なら、必要なのはリリースフラグと、おそらくキルスイッチ1つです。40人規模の実験フラグは、データではなくノイズを生みます。指標とサンプルサイズを言えるようになるまで、スキップしてください。
フィーチャーフラグは、ブランチとデプロイでは解決できない何を解決するか
重要なのは3つだけです。
未完成の作業を安全に出す。 長命のブランチは、マージが小さな戦争になるので害があります。フラグがあれば、新しいコードをオフのままmainに毎日マージできます。全員が1本のブランチにコミットし、未完成の部分はフラグが担うトランクベース開発の原動力がこれです。
段階的ロールアウト。 まず自分だけオンにし、次に1%、10%、最後に全員へ広げます。Fowler は、ユーザーIDを100で割った余りを使って1%程度のカナリア群を選ぶ方法を紹介しています。問題があっても、影響は全体ではなく数人に限られます。
素早い取り消し。 デプロイのロールバックには、ビルド、パイプライン、そして度胸が必要です。フラグを切り替えるのは1回の編集で済みます。悪い日には、数分の苦痛と1時間の苦痛の差になります。
個人開発の初日からベンダーは要りません。ただし、規律は必要です。
LaunchDarkly が必要か、JSONファイルで十分か
次のどれかが当てはまるまで、JSONファイルかデータベースのテーブルで十分です。非エンジニアがフラグを切り替える必要がある、割合ロールアウトやユーザー単位のターゲティングが要る、誰が何を変えたかの監査証跡が要る、同じフラグを読む複数のサービスを動かしている。
段階を登る順序は、おおよそ次のとおりだと考えています。
定数と環境変数。 コストはゼロです。個人開発の最初のリリースフラグには十分です。
実行時に読むテーブルかJSONファイル。 10行ほどのコードで、即座に切り替えられ、ベンダーは不要です。これだけで個人プロジェクトは驚くほど遠くまで行けます。
オープンソースかホスト型のフラグサービス。 ターゲティングルールや段階的ロールアウト、ほかの人も使えるUIが欲しくなったら。
エンタープライズ向けプラットフォーム。 コンプライアンス、承認フロー、数十人のエンジニアが関わってきたら。
ホスト型ツールは手順3と4を担当します。LaunchDarkly は最大手で、ターゲティングとガバナンスの機能が最も深く、その価格もそれを反映しています。
Statsig は、フラグを実験機能とプロダクト分析と一緒に提供します。フラグが何をしたかを測りたいなら、理にかなっています。
チームが自分一人なら、両方ともスキップしてください。3列のテーブルは、四半期に2回しか開かないダッシュボードより優れています。手作業の方法がなんらかの具体的な形で高くついたときにだけサービスを選んでください。たとえば、深夜に本番の設定を編集して後悔したときです。
知っておく価値のある保険があります。OpenFeature は、フラグを評価するためのベンダー中立なAPIを定義するCNCFのincubatingプロジェクトで、Node.js、Python、Go、Java、.NET、Webクライアントなどの SDK があります。標準のインターフェースに対してコードを書き、その下のプロバイダーを差し替えられます。最初の構成がいずれ足りなくなりそうなら、OpenFeature を通して配線しておけば、移行は設定の変更だけで済みます。

最初のフラグを散らかさずに追加するには
単一のリリースフラグと、いくつかの基本ルールから始めてください。私が今になって従えばよかったと思う方法です。
仕組みではなく機能にちなんだ名前をつける。 new-checkout-flow は、間違っていたら何が壊れるかを示します。flag_47 は、6か月後には何も示しません。
デフォルトはオフにし、オフが旧動作を意味するようにする。 「オフは旧版、オンは新版」という約束があると、プレッシャーの下でもシステムの動きを追えます。これを破ると、すべてのフラグがパズルになります。
評価は1か所で行う。 Fowler はこの修正を toggle inversion と呼んでいます。20ファイルに
if (flags.x)を散らす代わりに、システムの端で一度だけ判断し、その結果を渡します。判断点が1つなら、変更箇所もテストする場所も1つです。フラグを作った瞬間に、削除チケットを書く。 日付を付けてバックログに入れてください。Fowler は、短命なトグルに有効期限を付けることや、フラグが期限を過ぎると失敗するテストを書くことも提案しています。削除チケットのないフラグは、返済計画のない借金です。
重要な評価はすべてログに残す。 ユーザーがバグを報告したとき、フラグのどちら側にいたかを知りたいものです。それに答えられないなら、そのフラグは負債です。
テストで、人が過剰に作り込みがちです。フラグのすべての組み合わせをテストする必要はありません。ほとんどのフラグ同士は干渉しないからです。本番で期待する設定をテストし、新しいフラグをオフにしたときのフォールバックをテストし、任意で全部オンの1回のテストを回してドリフトを確認してください。
誰も言わない、フィーチャーフラグの本当のコスト
フラグは1つ増えるたびに、コードパスが倍になります。独立したフラグが10個あると、理論上は1,024通りの組み合わせになります。そのすべてをテストすることはできないので、本番で誰も想定していない組み合わせに当たることはあります。
もっと痛いのは、腐ったフラグです。ロールアウトが終わり、全員が新しい動作を使い、フラグは100%のまま残り、古い分岐がリポジトリに、誰も消す勇気のないコードとして残ります。半年後には、オフにしても安全かどうか誰も覚えていません。
この有名な例が、2012年8月の Knight Capital です。かつて引退した取引機能を有効にしていた古いフラグが、新しいコードで再利用されました。8台のサーバーのうち1台がデプロイを逃し、古いコードを動かし続けていました。45分で、同社の四半期報告書によれば約$440 million の損失が出ました。後の報道では約$460 million に近いとされています。これは実際の資金と実際のエンジニアを持つ取引会社です。だから、個人開発のプロジェクトが安全だとは言いません。教訓は小規模でも十分通用します。フラグ名は決して再利用しないこと、そして腐ったフラグは考古学の対象になる前に削除することです。

Fowler の考え方は、私が今も大事にしているものです。フラグは、維持コストのある在庫として扱うこと。チームによっては、生きているフラグの数に上限を設け、新しく1つ追加する前に既存の1つを削除することを求めます。個人開発なら、上限5つで十分です。
フィーチャーフラグを完全にスキップすべき場面
ツールのベンダーが認めるより、多くの場面です。
機能が小さく、gitで簡単に戻せて、デプロイが2分で終わるとき。フラグはブランチ、設定の参照元、忘れるものを増やします。git revert がフラグの切り替えより速いなら、フラグは見せかけです。
まだユーザーがいないとき。ゼロ人への段階的ロールアウトは、ただの遅延です。出して、ログを見て、直してください。
フラグでは戻せないデータベースのマイグレーション。フラグはUIで新しい列を隠せますが、落としたテーブルを戻すことはできません。スキーマ変更には、フラグの有無にかかわらず独自の expand-and-contract の計画が要ります。
フラグを使う価値があるのは、支払いや認証に関わる変更、未完成の作業を毎日マージしたいとき、外部依存が落ちるかもしれず、キルスイッチが欲しいときです。
フラグを公開したあと何を監視するか
フラグは公開の範囲を制御しますが、その後に何が起きるかが見えて初めて役立ちます。エラー率とレイテンシを見ずに10%のユーザーへ機能をオンにするのは、コイン投げに手順を足しただけです。
最初のロールアウトの前に、1分以内に次の3つへ答えられるようにしてください。フラグ付きのコホートでエラーが増えているか、レイテンシが悪化しているか、下流で何かが変わったか。小規模なプロダクトなら、死活監視とログ検索でほとんどカバーできます。Better Stack のようなツールなら、監視、ステータスページ、ログを1か所にまとめ、無料枠もあります。
いまの私のルールはこうです。フラグは、それに付けたアラートと同じだけ良い。アラートがなければ、暗闇の中でスイッチを入れているのと同じです。
今週、実際に何をするか。今すぐマージするのが怖い未完成の作業を1つ選んでください。テーブルかJSONファイルから読む真偽値の背後に置き、デフォルトはオフにして、今日mainにマージします。エディタを閉じる前に、2週間後の日付を付けて削除チケットを書いてください。そのあと自分だけにオンにして、1日使ってみてください。問題なければ範囲を広げ、だめならオフにするだけです。失うものは1分だけです。
あなたのコードベースで、100%のまま1か月以上経っているフラグはどれですか。それが最初の削除対象です。