Co to jest feature flag? Odpowiedź SRE z przykładem kodu

Summary

Feature flag to warunek w kodzie, odczytywany w czasie działania, który decyduje, czy dana ścieżka się wykonuje. Wyłączenie flagi zatrzymuje nową ścieżkę bez builda i deploya. Flagi dzielą się na cztery typy o różnym cyklu życia, a każda potrzebuje daty usunięcia. Traktowane jak pokrętło blast radius, zamieniają wydanie w odwracalną decyzję. Zanim wybierzesz platformę, zmierz latencję SDK, model rozliczeń i zachowanie przy awarii sieci.

Pulpit operacyjny nocą z dwoma monitorami i panelem fizycznych przełączników na pierwszym planie

Jest 03:12, a wskaźnik błędów w checkoucie właśnie przekroczył 4 procent. Zmiana, która to spowodowała, weszła na produkcję sześć godzin temu. Nikt nie chce cofać całego wydania, bo niesie też dwie niezwiązane poprawki. Więc co to jest feature flag w takiej sytuacji? To warunek w kodzie, odczytywany w czasie działania, który decyduje, czy dana ścieżka kodu się wykonuje. Wyłączasz go, a nowa ścieżka przestaje działać, bez builda i bez deploya. To cała idea. Reszta to operacje.

Czym naprawdę jest feature flag (i czym nie jest)

Feature flag to punkt decyzyjny. Gdzieś w kodzie jest if, a wartość, którą czyta, pochodzi spoza binarki: z serwisu konfiguracji, wiersza w bazie, SDK dostawcy albo zmiennej środowiskowej, którą można zmienić bez restartu.

const useNewPricing = await flags.isEnabled("new-pricing-engine", {
  userId: user.id,
  plan: user.plan,
  region: request.region,
});

return useNewPricing
  ? newPricingEngine.quote(cart)
  : legacyPricing.quote(cart);

Z tego fragmentu wynikają trzy rzeczy. Stara ścieżka nadal musi istnieć i nadal musi działać. Flaga potrzebuje kontekstu (kto pyta), jeśli chcesz czegoś mądrzejszego niż włączone albo wyłączone. A ewaluacja leży na gorącej ścieżce żądania, więc jej opóźnienie i sposób awarii to teraz twój problem.

Ludzie używają zamiennie określeń „feature toggle” i „feature flag”. Samo słowo nie ma znaczenia, liczy się zachowanie: oddzielasz wdrożenie kodu od jego wydania. Kod trafia na produkcję w ukryciu, a człowiek lub system decyduje później, kto go zobaczy.

Cztery rodzaje flag i dlaczego mieszanie ich szkodzi

Większość problemów z flagami bierze się z traktowania wszystkich flag jako jednej rzeczy. Taksonomia feature toggles Martina Fowlera dzieli je według tego, jak długo żyją i jak dynamiczna jest decyzja. W praktyce to się sprawdza.

Release toggles są przejściowe. Ukrywają niedokończoną pracę za flagą, żebyś mógł scalać do trunk codziennie. Zdaniem Fowlera rzadko powinny przeżyć tydzień albo dwa. Decyzja jest statyczna: każde żądanie dla danego wydania dostaje tę samą odpowiedź.

Experiment toggles kierują różnych użytkowników do różnych wariantów. Żyją tyle, ile trzeba, by osiągnąć istotność statystyczną: od godzin do tygodni, nie dłużej. Decyzja zapada dla każdego żądania.

Ops toggles sterują zachowaniem operacyjnym: wyłączają nieistotną funkcję pod obciążeniem, przełączają na zapasową zależność, wyłączają drogie zapytanie. Kilka z nich zamienia się w długo żyjące kill switche. Muszą przełączać się w ciągu sekund, a to wyklucza wszystko, co wymaga wydania.

Permission toggles blokują funkcje według planu lub uprawnień. Mogą żyć latami, a decyzja zapada dla każdego użytkownika przy każdym żądaniu.

Błąd polega na nadaniu wszystkim czterem tego samego cyklu życia. Permission toggle potrzebuje właściciela i ścieżki audytu na zawsze. Release toggle potrzebuje daty usunięcia w dniu utworzenia. Jeśli po nazwie nie widać, jakiego jest typu, nie będziesz wiedzieć, które można bezpiecznie usunąć.

Ręka pociągająca czerwoną dźwignię kill switcha na ciemnej szafie sterowniczej

Dlaczego SRE się tym interesują: kontrola blast radius

Dla zespołu platformowego ciekawa nie jest w flagach możliwość testów A/B. Ciekawe jest to, że flaga zamienia wydanie z wydarzenia w pokrętło.

Bez flag deploy wystawia na zmianę 100 procent ruchu naraz. Jedynym cofnięciem jest kolejny deploy, który trwa tyle, ile trwa twój pipeline, plus czas, jaki człowiek potrzebuje, żeby mieć pewność. Z flagami możesz wystawić 1 procent użytkowników, obserwować wskaźnik błędów i p99, a potem przejść na 5, 25, 50. Blast radius to procent, który wybrałeś, a cofnięcie to zmiana konfiguracji, która rozchodzi się w ciągu sekund.

To zmienia średni czas odzyskania sprawności bardziej niż większość inwestycji w narzędzia. Pytanie po incydencie przestaje brzmieć „dlaczego wycofanie zajęło 40 minut”, a staje się „dlaczego to nie było za flagą”.

Pokrętło ma jednak haczyk. Ktoś musi patrzeć na sygnały i je przekręcać, a o 03:12 ten ktoś jest zmęczony. Użyteczna wersja systemu flag wiąże pokrętło z celem poziomu usług (SLO): jeśli wskaźnik błędów zużywa określony udział budżetu, rollout zatrzymuje się i wycofuje bez udziału człowieka. Większość zespołów buduje to ręcznie, webhookiem z narzędzia alertowego do API flag. To kilkaset linii kodu, które zwracają się już przy pierwszej nocy, w której zadziałają.

W praktyce oznacza to jedno: zanim włączysz rollout, zapisz, która metryka ma cię zatrzymać i kto ma prawo przekręcić pokrętło z powrotem. Pół godziny takiej rozmowy oszczędza kwadrans paniki o trzeciej w nocy.

Rachunek przychodzi: dług flag i lekcja z Knight Capital

Każda dodana flaga teoretycznie podwaja liczbę ścieżek przez ten kod. W praktyce testujesz garść kombinacji i masz nadzieję. Fowler zaleca traktowanie flag jak zapasów z kosztem utrzymania: dodaj zadanie usunięcia do backlogu w chwili utworzenia flagi, ustaw daty wygaśnięcia, a w najbardziej rygorystycznych zespołach spraw, żeby build się wywalał, gdy wygasła flaga wciąż jest w kodzie.

Najdroższa wersja tej lekcji to Knight Capital. 1 sierpnia 2012 roku nowe wdrożenie ponownie użyło starej flagi, która kiedyś sterowała wycofaną funkcją. Jeden serwer ominął wdrożenie i nadal uruchamiał stary kod. W ciągu pierwszych 45 minut po otwarciu rynku router firmy wysłał na rynek ponad 4 miliony zleceń, próbując zrealizować 212 zleceń klientów, jak zapisano w decyzji SEC wobec Knight Capital. Artykuł Fowlera wskazuje stratę rzędu 460 mln $ jako przestrogę przed flagami, którymi nikt nie zarządza.

Sama flaga nie była jedynym błędem. Ręczne wdrożenie, brak kill switcha i powolne wykrywanie też się przyczyniły. Ale ponowne użycie martwej nazwy flagi to szczegół, który każdy zespół platformowy powinien mieć powieszony na ścianie. Nigdy nie przypisuj flagi do innej funkcji. Usuń starą, utwórz nową i uczyń usuwanie pełnoprawnym krokiem.

Nie chodzi o to, by bać się flag. Chodzi o to, by każda z nich miała datę urodzenia i datę śmierci, zapisane w systemie, zanim trafi do kodu. Zespół, który przegląda kilkadziesiąt flag miesięcznie, może zrobić cotygodniowy przegląd listy flag przeterminowanych. Zajmuje dwadzieścia minut i zwykle wystarcza.

Notatnik z odręcznymi schematami przepływu obok klawiatury i laptopa na drewnianym biurku

Zbudować samemu czy kupić platformę flag?

Samodzielnie zbudowany system flag zaczyna się jako plik konfiguracyjny i wartość logiczna. To wystarcza dla pierwszej garści release toggles w jednej usłudze. Przestaje wystarczać, gdy potrzebujesz rolloutów procentowych, które pozostają stabilne dla danego użytkownika, reguł targetowania według segmentu, dziennika audytu zmian oraz zmiany flagi, która dociera do każdej instancji w ciągu sekund, bez lawiny zapytań do magazynu konfiguracji.

Wtedy porównujesz platformy na mierzalnych kryteriach: latencja ewaluacji w SDK (lokalnie kontra wywołanie sieciowe), streaming kontra polling przy aktualizacjach, szczegółowość reguł targetowania, wsparcie dla wielu środowisk i sposób, w jaki cennik rośnie wraz z ruchem.

Liczniki różnią się bardziej niż listy funkcji.

LaunchDarkly jest referencyjną implementacją tej kategorii: dojrzałe targetowanie, chronione wydania i rozbudowana powierzchnia integracji. Plany oparte na zużyciu naliczają opłaty za połączenia z usługami i za tysiąc miesięcznych aktywnych użytkowników po stronie klienta, więc aplikacja konsumencka z dużą anonimową publicznością może zobaczyć, że rachunek rośnie w sposób, którego zespół działający tylko po stronie backendu nie zauważy. Argument za jest realny: jeśli potrzebujesz governance i audytu na skalę enterprise, ta platforma miała najdłużej czas, by to utwardzić.

Statsig łączy flagi z eksperymentami i analityką produktu, a opłaty nalicza za zdarzenia. Pasuje do zespołów, które traktują flagi głównie jako powierzchnię eksperymentów. Jeśli twój przypadek to przede wszystkim ops toggles i kill switche, płacisz za analitykę, której możesz nie czytać. Zauważ też, że dostawca zmieniał właściciela dwukrotnie od września 2025 roku, co warto uwzględnić w przeglądzie ryzyka dostawcy.

Którąkolwiek wybierzesz, przetestuj tryb awarii, zanim podpiszesz umowę. Zablokuj dostęp sieciowy SDK na stagingu i sprawdź, co robi aplikacja. Dobry SDK obsługuje ostatnie znane wartości flag z cache i głośno o problemie loguje. Zły blokuje ścieżkę żądania.

Obserwowalność to połowa systemu flag

Flaga bez telemetrii to zgadywanie. Minimalnie użyteczna konfiguracja dołącza stan flagi do każdego trace'a i wiersza logu dla danego żądania, tak żebyś przy skoku błędów mógł pogrupować dane według wariantu flagi i zobaczyć, czy to nowa ścieżka jest przyczyną.

Datadog i podobne platformy all-in-one ułatwiają podział według wariantów, gdy SDK taguje spany. Trzeba jednak pamiętać, że rozliczanie za host i za sygnał szybko rośnie, gdy dodajesz tagi o wysokiej kardynalności, takie jak klucz flagi plus wariant plus segment użytkowników. Wybieraj świadomie wymiary, po których tagujesz.

Grafana jest tańszą drogą, jeśli już używasz Prometheus i OpenTelemetry. Dashboardy uwzględniające flagi zbudujesz sam, co kosztuje czas inżynierów, ale daje pełną kontrolę nad etykietami, które emitujesz. Dla zespołu 50 do 500 inżynierów z grupą platformową ten kompromis bywa właściwy.

Niezależnie od narzędzia zasada jest ta sama: tagując, trzymaj się kilku wymiarów, które odpowiadają na pytania z incydentu. Typ flagi, wariant i region zwykle wystarczają. Identyfikator użytkownika zostaw w logach, a nie w metrykach, bo tam eksploduje liczba szeregów czasowych.

Inżynier idący wzdłuż alejki szaf serwerowych oświetlonej na niebiesko i bursztynowo

Krótki runbook dla pierwszej flagi na produkcji

Jeśli wprowadzasz flagi do zespołu, który ich nie ma, zachowaj pierwsze wdrożenie nudne.

  1. Wybierz jedną zmianę z jasną metryką sukcesu, na przykład wskaźnik błędów checkoutu albo p99 jednego endpointu.

  2. Nazwij flagę jej typem i właścicielem, na przykład release.checkout.new-tax-calc.owner-payments.

  3. Od razu załóż zadanie usunięcia i ustaw datę wygaśnięcia najpóźniej za dwa tygodnie.

  4. Wystaw zmianę na 1 procent, wstrzymaj się przez pełny cykl ruchu, potem zwiększaj. Z góry zdefiniuj próg, przy którym cofasz.

  5. Uczyń cofnięcie jedną komendą albo przyciskiem i przećwicz je raz na stagingu, zanim będziesz tego potrzebować w nocy.

  6. Gdy 100 procent utrzymało się przez kilka dni, usuń flagę i starą ścieżkę kodu w tej samej zmianie.

Mało efektowna jest część 6. Zespoły, które ją pomijają, kończą z kilkoma setkami flag, bez nikogo, kto wie, co robi połowa z nich, i z ryzykiem na miarę Knight Capital w repozytorium.

Po pierwszym rolloutcie zapisz, co się wydarzyło, nawet jeśli wszystko poszło dobrze. Krótka notatka o tym, ile czasu zajęło wykrycie problemu i ile razy ktoś musiał sięgnąć po przycisk, daje następnej fladze lepszy punkt startowy niż pamięć zespołu.

Jak wyglądałby twój ostatni incydent za flagą?

Weź ostatni incydent produkcyjny, który twój zespół opisał w post-mortemie. Zadaj trzy pytania. Czy zmiana mogła wyjść w ukryciu? Czy jedna osoba mogłaby ją wyłączyć w mniej niż minutę, bez deployu? Czy alert powiedziałby, który wariant zawodzi?

Jeśli odpowiedzi brzmią nie, nie, nie, masz swojego pierwszego kandydata na flagę i pierwszą uczciwą wycenę tego, ile dziś kosztuje cofnięcie. Post-mortem powie to, co powie. Lepsze pytanie brzmi: ile z niego dało się zmniejszyć, zanim zadzwonił pager?

Frequently asked questions

Co to jest feature flag w prostych słowach?
Feature flag to warunek w kodzie działający w czasie wykonania, który decyduje, czy dana ścieżka kodu się wykona. Wartość pochodzi spoza binarki, na przykład z serwisu konfiguracji albo SDK dostawcy, dzięki czemu zachowanie można zmienić bez nowego deployu.
Jaka jest różnica między feature flag a feature toggle?
W praktyce żadna. Obie nazwy opisują ten sam mechanizm. Niektórzy dostawcy używają słowa toggle na określenie praktyki, a flag na implementację w kodzie, ale zespoły używają tych terminów zamiennie.
Jakie są główne typy feature flag?
Najczęściej wyróżnia się cztery: release toggles, które ukrywają niedokończoną pracę, experiment toggles do testów A/B, ops toggles do sterowania w czasie działania, takie jak kill switche, oraz permission toggles do blokowania według planu lub uprawnień. Każdy typ ma inny oczekiwany czas życia.
Jak długo powinna żyć feature flaga?
To zależy od typu. Release toggles zwykle powinny zniknąć w ciągu tygodnia albo dwóch. Experiment toggles żyją tak długo, jak trzeba, by osiągnąć istotność statystyczną. Kill switche operacyjne i permission toggles mogą żyć latami, pod warunkiem że mają jasnego właściciela.
Czym jest kill switch w oprogramowaniu?
Kill switch to długo żyjąca flaga operacyjna, która pozwala operatorowi natychmiast wyłączyć funkcję lub zależność na produkcji, bez deployu. Służy do łagodnego ograniczania działania pod obciążeniem albo do zatrzymania wadliwej zmiany.
Czy warto zbudować własny system flag, czy kupić gotowy?
Plik konfiguracyjny i wartość logiczna wystarczą dla kilku release toggles w jednej usłudze. Gdy potrzebujesz stabilnych rolloutów procentowych, targetowania według segmentów, dziennika audytu i szybkiej propagacji między instancjami, porównaj platformy pod kątem latencji SDK, mechanizmu aktualizacji, szczegółowości targetowania i sposobu, w jaki rośnie cennik.
Czy feature flagi mogą spowodować awarię?
Tak. Częste przyczyny to ponowne użycie starej nazwy flagi, pozostawione martwe ścieżki kodu i nieprzetestowane kombinacje flag. Incydent Knight Capital z 2012 roku dotyczył ponownie użytej flagi. Traktuj flagi jak zapasy z datą wygaśnięcia i nigdy nie przypisuj flagi do nowej funkcji.