ひとことで言うと#
コード上にif文の分岐(トグル)を埋め込み、設定を変えるだけで機能のON/OFFを切り替えられるようにする手法。デプロイ(コードを配置すること)とリリース(ユーザーに公開すること)を分離する。
押さえておきたい用語#
- リリーストグル(Release Toggle)
- 未完成の機能を本番に隠すための短命なフラグのこと。全ユーザーにリリース完了後は速やかに削除する。
- 実験トグル(Experiment Toggle)
- A/Bテスト用のユーザーセグメント別フラグのこと。コンバージョン率の比較など、データ駆動の意思決定に使用する。
- オペレーショントグル(Operations Toggle)
- 高負荷時に重い機能をOFFにするための運用向けフラグのこと。サーキットブレーカーに近い役割を果たす。
- 技術的負債(Technical Debt)
- フィーチャートグルの文脈では、役目を終えた古いトグルが放置された状態のこと。コードの可読性を低下させ、テストの複雑性を増大させる。
フィーチャートグルの全体像#
こんな悩みに効く#
- 未完成の機能をmainブランチにマージしたいが、ユーザーに見せたくない
- リリースのタイミングをビジネス側がコントロールしたい
- 問題が起きた機能を、再デプロイなしで即座に無効化したい
基本の使い方#
フィーチャートグルには4つの種類がある。
- リリーストグル: 未完成の機能を隠す。短命(リリース後に削除)
- 実験トグル: A/Bテスト用。ユーザーセグメント別に切り替え
- オペレーショントグル: 負荷時に重い機能をOFFにする。運用向け
- パーミッショントグル: 特定ユーザー・プランにだけ機能を公開
ポイント: 目的に応じて適切な種類を選ぶ。寿命が違えば管理方法も違う。
トグルの状態を管理する仕組みを用意する。
- シンプルな場合: 環境変数や設定ファイル
- 本格的な場合: LaunchDarkly、Unleash、Flagsmithなどのフィーチャーフラグサービス
- 再デプロイなしで切り替えられることが重要
ポイント: 最初は設定ファイルで十分。規模が大きくなったら専用サービスを検討する。
条件分岐としてトグルをコードに埋め込む。
- トグルの判定ロジックは1箇所に集約する
- トグルがOFFの場合の挙動(旧機能またはフォールバック)を明確にする
- テストでは両方の状態(ON/OFF)をテストする
ポイント: トグルの分岐点は最小限にし、なるべく上位のレイヤーで切り替える。
役目を終えたトグルを速やかに除去する。
- リリーストグルは全ユーザーにリリース完了後に削除
- トグルの棚卸しを定期的に行う(月1回など)
- 削除期限をトグル作成時に設定しておく
ポイント: 古いトグルの放置は技術的負債の温床。トグルにも「賞味期限」をつける。
具体例#
状況: 新しいAIレコメンドエンジンを開発中。mainブランチに継続的にマージしたいが、まだ全ユーザーに見せたくない。
リリーストグル: NEW_RECOMMENDATION_ENGINEフラグを作成。デフォルトOFF。
段階リリース:
- 社内スタッフだけON → 社内でフィードバック収集
- プレミアムプランユーザーの10%にON → CTR **+15%**を確認
- 全プレミアムユーザーにON → 安定稼働確認
- 全ユーザーにON → 問題なし
トグル削除: 全ユーザーリリースの2週間後、旧レコメンドのコードとトグルをコードベースから削除。
結果: 3ヶ月の開発期間中、一度も長寿命のフィーチャーブランチを作らずにmainで開発を継続できた。
状況: 新しい検索機能をリリースしたが、想定外のクエリパターンでDBの負荷が急増。CPU使用率が**95%**に達し、サービス全体のレスポンスが悪化。
オペレーショントグル: NEW_SEARCH_FEATUREフラグをLaunchDarklyの管理画面からOFFに切り替え。再デプロイなし、30秒で旧検索に切り戻し。
After: DBのCPU使用率が95%→**40%**に低下。サービスが正常化した後、根本原因(インデックス不足)を修正し、翌日に再度ONに。
結果: トグルがなければ、緊急hotfixのビルド→テスト→デプロイで最低30分のダウンタイムが発生していた。トグルのおかげで影響時間を30秒に抑制。
Before: フィーチャートグルを3年間運用。削除されずに残ったトグルが103個。コードの可読性が低下し、「このフラグはまだ使われているのか?」の確認に毎回30分以上かかる状態。
棚卸し施策:
- 全103個のトグルをリスト化し、最終変更日とON/OFF状態を確認
- 1年以上ONのまま放置されているトグルは「常にON」と判断し、分岐ごと削除
- トグル作成時に
expires_atフィールドを必須化。期限超過でCIが警告を出す
After: トグル数が103個→12個(88%削減)。コードの可読性が大幅に向上し、新メンバーのオンボーディング時間が20%短縮。
やりがちな失敗パターン#
- トグルを削除せず放置する — 使われていないトグルが100個以上溜まり、コードの可読性が低下する。トグル作成時に削除期限を設定すること
- トグルの組み合わせ爆発 — 複数のトグルが相互に影響するケースをテストしきれない。トグル同士の依存関係を作らない設計にすること
- テストでトグルのOFF側を検証しない — ON側だけテストして、OFF側(旧機能)が壊れていることに気づかない。両方の状態を自動テストでカバーすること
- トグルの分岐をコード全体に散りばめる — 同じトグルのif文がコードの各所に散在し、削除時の影響範囲が把握困難に。分岐点を1箇所に集約すること
まとめ#
フィーチャートグルは 「デプロイとリリースを切り離す」 強力なツール。開発中の機能を安全にmainにマージし、ビジネスの都合に合わせてリリースタイミングを制御できる。ただし、トグルの削除を怠ると技術的負債になるので、ライフサイクル管理を忘れずに。