Зачем нужны Feature Flags

Feature flag — это условие в коде: «если флаг включён → показать новую версию». Ключевое свойство — состояние флага меняется в рантайме (через конфиг-сервер, Remote Config или feature management платформу) без нового деплоя.

Это решает несколько критических задач при разработке продукта:

  • Trunk-based development: разработчики мерджат код в main непрерывно, даже незаконченный — флаг скрывает его от пользователей
  • Canary rollout: постепенное включение на 1% → 10% → 100% с мониторингом метрик на каждом шаге
  • Kill switch: мгновенное отключение проблемной функции без хотфикса и деплоя (секунды vs. десятки минут)
  • Сегментированный доступ: показывать фичу только бета-пользователям, определённым гео или корпоративным клиентам

Типы Feature Flags

Тип Назначение Срок жизни
Release flag Скрыть незаконченный код Короткий (до релиза)
Experiment flag A/B тест новой функции Средний (до объявления победителя)
Ops flag Kill switch, circuit breaker Долгосрочный (дежурный)
Permission flag Платный/premium доступ Постоянный

Feature Flags в мобильной разработке

В мобайле особая сложность — нельзя мгновенно обновить код у всех пользователей (App Store review, фрагментация версий). Feature flags через Remote Config (Firebase, Amplitude, AWS AppConfig) решают эту проблему: серверная конфигурация меняется в реальном времени без обновления приложения.

Важно: Флаг в мобильном приложении считывается при старте сессии (или по интервалу). Если пользователь не перезапустит приложение — он увидит новое значение только после следующего запуска. Учитывайте это при планировании kill switch.

Типичные ошибки

  • Flag debt: не удалять флаги после завершения rollout. Флаг с двумя ветками кода — это скрытое техническое долговое бремя. Внедрите процесс: каждый флаг имеет тикет на удаление.
  • Тестирование только «включённой» ветки: QA должен проверять оба состояния флага.
  • Флаг в критическом path без fallback: если сервис конфигурации недоступен, убедитесь, что дефолтное значение флага безопасно (обычно — «выключен»).