← Назад в словарь

Feature flag

Feature flag — переключатель функции

TL;DR

Feature flag (feature toggle) — паттерн, при котором поведение системы меняется через конфигурацию, а не через деплой кода. Позволяет включать/выключать функциональность для пользователей, групп или процента трафика без передеплоя.

Краткое определение

Feature flag — механизм управления функциональностью через конфигурацию (флаги), который позволяет включать или выключать функции динамически, без изменения кода и повторного деплоя.

Оригинал и перевод

  • Язык: английский
  • Оригинал: Feature flag / Feature toggle
  • Буквальный перевод: флаг функции / переключатель функции
  • Русские аналоги: фича-флаг, переключатель функций, флаг функциональности

Синонимы и варианты написания

  • Feature toggle
  • Feature switch
  • Фича-флаг
  • Флаг функциональности
  • Kill switch (для аварийного отключения)

Где используется

  • Web-приложения — постепенный rollout новых функций
  • Микросервисы — управление функциями между сервисами
  • A/B тестирование — включение разных вариантов для разных групп
  • Постепенный rollout — 1% → 10% → 50% → 100% пользователей
  • Emergency kill switch — аварийное отключение проблемной функции
  • Разработка в ветке — merge в master без включения функции

Когда это важно

Feature flags критичны в следующих сценариях:

  • Частые релизы — несколько деплоев в день
  • Высокие требования к доступности — нельзя рисковать всем функционалом
  • A/B тестирование — сравнение вариантов функции
  • Canary release — тестирование на части пользователей
  • Разработка в команде — merge конфликтующих изменений без включения

Типы feature flags

1. Release Flags (релизные)

Короткоживущие флаги для постепенного rollout:

// Включение новой функции для 10% пользователей
if (FeatureFlag::isEnabled('new_checkout', $userId, 10)) {
    // Новая логика checkout
} else {
    // Старая логика
}

2. Experiment Flags (экспериментальные)

Для A/B тестирования:

// 50% пользователей видят вариант A, 50% — вариант B
$variant = FeatureFlag::getVariant('checkout_button_color', $userId);
// 'green' или 'blue'

3. Ops Flags (операционные)

Для аварийного отключения:

// Kill switch для проблемной функции
if (!FeatureFlag::isEnabled('payment_service')) {
    // Возвращаем ошибку или fallback
    return $this->fallbackPayment();
}

4. Permission Flags (флаги разрешений)

Для доступа по ролям/группам:

// Только для админов
if (FeatureFlag::isEnabledForRole('admin_dashboard', 'admin')) {
    // Показываем админ-панель
}

Реализация feature flags

Простая реализация (PHP + Redis)

class FeatureFlag {
    private Redis $redis;
    
    public function isEnabled(string $flag, ?int $userId = null, int $percentage = 100): bool {
        // Проверяем, существует ли флаг
        $value = $this->redis->get("feature:{$flag}");
        if ($value === null) {
            return false; // Флаг не найден
        }
        
        // Если процент < 100, используем hash от userId
        if ($percentage < 100 && $userId !== null) {
            $hash = crc32("{$flag}:{$userId}") % 100;
            return $hash < $percentage;
        }
        
        return (bool) $value;
    }
    
    public function enable(string $flag): void {
        $this->redis->set("feature:{$flag}", true);
    }
    
    public function disable(string $flag): void {
        $this->redis->del("feature:{$flag}");
    }
}

// Использование
$features = new FeatureFlag($redis);

if ($features->isEnabled('new_checkout', $userId, 25)) {
    // 25% пользователей увидят новый checkout
}

Готовые решения

РешениеЯзыкОписание
LaunchDarklySaaSПлатформа управления feature flags
UnleashOpen SourceSelf-hosted решение
FlagsmithOpen SourceFeature flags + A/B тесты
GrowthBookOpen SourceA/B тестирование и flags
ConfigCatSaaSFeature flags для команд

Пример с LaunchDarkly

const LaunchDarkly = require('launchdarkly-node-server-sdk');

const client = LaunchDarkly.init('sdk-key-123');

const user = { key: 'user123', email: 'user@example.com' };

client.waitForInitialization().then(() => {
  const enabled = client.variation('new-checkout', user, false);
  
  if (enabled) {
    // Показываем новый checkout
  } else {
    // Показываем старый
  }
});

Best practices для feature flags

✅ Делайте

  • Короткоживущие флаги — удаляйте после стабилизации функции
  • Централизованное управление — один сервис/библиотека для всех флагов
  • Логирование — записывайте, какие флаги и когда включались
  • Мониторинг — отслеживайте влияние флагов на производительность
  • Документирование — описывайте, зачем нужен каждый флаг
  • Тестирование — тестируйте оба пути (включено/выключено)

❌ Не делайте

  • Вложенные флаги — не усложняйте логику (if (flag1 && !flag2 || flag3))
  • Флаги навсегда — технический долг накапливается
  • Хардкод значений — храните флаги в конфигурации, не в коде
  • Слишком много флагов — каждый флаг добавляет сложность

Управление жизненным циклом

Создание → Тестирование → Rollout → Стабилизация → Удаление
    ↓           ↓           ↓          ↓            ↓
  Dev         QA         Prod      Stable      Cleanup

Пример процесса

# feature-flags.yml
new_checkout:
  created: 2026-01-15
  owner: @developer-name
  status: rollout  # creating, testing, rollout, stable, deprecated
  rollout:
    percentage: 25
    started: 2026-02-01
  remove_after: 2026-03-01  # Плановая дата удаления

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

  • Флаги без удаления — код обрастает «мертвыми» ветками
  • Слишком много флагов — невозможно понять, что включено
  • Нет мониторинга — неясно, кто и когда использует флаг
  • Флаги в БД — медленное чтение, кэшируйте в Redis
  • Изменение логики без тестов — можно сломать существующую функцию

Аналоги и связанные термины

  • Canary release — постепенный релиз на части трафика
  • Blue/Green deployment — развёртывание в двух средах
  • Kill switch — аварийное отключение
  • A/B testing — тестирование вариантов
  • Continuous delivery — непрерывная доставка

Смотри также (статьи на сайте)

Смотри также (сниппеты)

Смотри также (термины)

Мини-FAQ

Можно ли жить без feature flags?

Ответ: Да, но риски релизов и откатов будут выше. Feature flags — это страховка: надеешься, что не понадобится, но лучше иметь.

Флаги — это навсегда?

Ответ: Нет! Флаги должны удаляться после стабилизации функции (обычно 2-4 недели). Иначе код превращается в «швейцарский сыр» из условий.

Как бороться с накоплением флагов?

Ответ:

  1. Создавайте тикет на удаление флага при его создании
  2. Используйте remove_after дату в конфигурации
  3. Автоматически предупреждайте о старых флагах
  4. Проводите «чистку» раз в квартал

Feature flags замедляют систему?

Ответ: Минимально, если реализовано правильно (кэш в Redis, не БД). Проверка флага занимает < 1 мс.