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
}
Готовые решения
| Решение | Язык | Описание |
|---|---|---|
| LaunchDarkly | SaaS | Платформа управления feature flags |
| Unleash | Open Source | Self-hosted решение |
| Flagsmith | Open Source | Feature flags + A/B тесты |
| GrowthBook | Open Source | A/B тестирование и flags |
| ConfigCat | SaaS | Feature 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 — непрерывная доставка
Смотри также (статьи на сайте)
- CI/CD GitHub Actions: workflow, secrets, tests, deploy — автоматизация деплоя
- Bitrix: проблема или просто инструмент — управление рисками
Смотри также (сниппеты)
- Идемпотентный агент с блокировкой — защита от параллельного запуска
- PHP 8.5: pipe-оператор для пайплайна — обработка данных
Смотри также (термины)
- Blue/Green deployment — стратегия развёртывания
- Canary release — постепенный релиз
- Technical debt — технический долг
Мини-FAQ
Можно ли жить без feature flags?
Ответ: Да, но риски релизов и откатов будут выше. Feature flags — это страховка: надеешься, что не понадобится, но лучше иметь.
Флаги — это навсегда?
Ответ: Нет! Флаги должны удаляться после стабилизации функции (обычно 2-4 недели). Иначе код превращается в «швейцарский сыр» из условий.
Как бороться с накоплением флагов?
Ответ:
- Создавайте тикет на удаление флага при его создании
- Используйте
remove_afterдату в конфигурации - Автоматически предупреждайте о старых флагах
- Проводите «чистку» раз в квартал
Feature flags замедляют систему?
Ответ: Минимально, если реализовано правильно (кэш в Redis, не БД). Проверка флага занимает < 1 мс.