Vad är feature flags? Guide till SLO-gated utrullning
Summary
Feature flags är villkorliga kontroller i din applikationskod som separerar deployment från release. De gör att du kan shipper kod utan att aktivera den för användare, rulla ut progressivt med SLO-gate och stänga av funktioner utan nytt bygge. Fyra flaggtyper dominerar i produktion: release, experiment, ops och behörighet. Utan rätt arkitektur, tydliga ägare och aktivt flaggunderhåll är de teknisk skuld i rörelse som påverkar p99-latens och incidentrespons.
Vad är feature flags? Deployment och release är inte samma händelse
Vad är feature flags? De är villkorliga kontroller i din applikationskod som styr vilka kodvägar som exekveras för en given användare, session eller miljö, utan att du behöver shipper ett nytt bygge. En flagga som heter new_checkout_flow satt till false för 99% av din användarbas betyder att du deployade den koden för två veckor sedan. Du har bara inte slagit på den ännu. Det kontrakt de upprättar är precist: deployment och release blir två separata händelser. För team som kör continuous deployment i skala är det kontraktet bärande.
Deployment och release är inte samma händelse
De flesta team lär sig skillnaden efter en dålig utrullning. En funktion shippas på tisdagseftermiddagen, något i request-tracen börjar bete sig annorlunda på onsdagsmorgonen, och när någon öppnar en utredning täcker diff:en fyra commits och två servicegränser. Att attribuera kausalitet i det scenariot är genuint svårt.
Feature flags tvingar fram precision. När koden bakom en flagga mergas och deployas ligger den inaktiv i produktion. Du bekräftar att deployment lyckades, observerar baslinjemätvärden i några timmar eller dagar, och verifierar att inget försämrats. Sedan flippar du flaggan för 1% av trafiken. Nu har du en enda attributerbar variabel. Om felfrekvensen stiger på den flaggade sökvägen debuggar du inte ett koddiff. Du togglar ett konfigurationsvärde.
Den separationen är inte primärt ett hastighetsargument. Det är ett blast radius-argument. En release som påverkar 1% av sessionerna och går fel är återställbar på minuter. En release som påverkar 100% av sessionerna och går fel är en allvarlig incident.
Mekanismen i sig är enkel. I TypeScript ser en flaggutvärdering ungefär ut så här:
const showNewCheckoutFlow = flagClient.variation(
'new_checkout_flow',
{ userKey: session.userId, custom: { plan: user.plan } },
false // default om flaggtjänsten inte är nåbar
);
if (showNewCheckoutFlow) {
return renderNewFlow(cart);
}
return renderLegacyFlow(cart);Standardvärdet false är inte en formalitet. Det är det beteende dina användare får om flaggutvärderingstjänsten har en nätverkspartition. Definiera det medvetet, inte av misstag.
De fyra flaggtyperna som faktiskt spelar roll i produktion
Inte alla feature flags tjänar samma operativa syfte. Att behandla dem identiskt i din kodbas och dina hanteringsverktyg är ett tillförlitligt sätt att skapa förvirring under incidenter och samla på sig flaggskuld.
Release-flaggor gaear nya funktioner under utveckling och utrullning. De är förväntade att vara temporära: skapade när arbetet med en funktionsgren börjar, borttagna när funktionen når 100% av användarna och teamet bekräftat stabilitet. Release-flaggor utan borttagningsdatum och utan angiven ägare blir permanent inredning i din kodbas.
Experimentflaggor driver A/B-tester och multivariata experiment. De är kopplade till analytiska kohortidentifierare och deras livscykel begränsas av experimentet. När experimentet avslutas försvinner flaggan med det. Det vanliga misstaget: att hålla den vinnande varianten bakom flaggan på obestämd tid med argumentet att borttagning "inte är brådskande." Två år senare är experimentflaggan en del av den kritiska sökvägen och ingen minns vilken variant som är aktiv.
Ops-flaggor är kill switches och circuit breakers. Till skillnad från release-flaggor är de utformade som permanent infrastruktur. En disable_ml_recommendations-flagga som låter dig kringgå ett långsamt ML-inferenslager när dess SLO försämras är något du vill ha tillgängligt klockan 3 på natten utan att behöva läsa dokumentation. Dessa flaggor ska utvärderas lokalt, ha ett väldefinierat fallback-värde, och testas regelbundet under normala operationer, inte upptäckas under press.
Behörighetsflaggor kontrollerar åtkomst per användarnivå, kontoplan eller betakohort. De är långlivade av design. Förvirringsrisken: behörighetsflaggor ser ofta ut som release-flaggor för en läsare som inte känner till historiken. En tydlig namnkonvention spelar större roll här än någon annanstans.

En procentuell utrullning utan SLO-gate är bara långsam deployment
Här slutar de flesta feature flag-implementationer i förtid. Plattformsteamet kopplar ihop ett utrullningsschema: 1% på måndag, 5% tisdag, 25% onsdag, 100% fredag. De dokumenterar det, delar det med intressenter, och kallar det progressiv leverans.
Men "progressiv" utan ett valideringsvillkor vid varje steg är uppskjuten risk, inte reducerad risk. Procentratten styr exponering. Den validerar inte säkerhet.
Det som gör en stegvis utrullning operativt meningsfull är SLO-gaten mellan varje steg. Innan du går från 5% till 25% ska något besvara: är felfrekvensen på den flaggade kodsökvägen inom SLO-budgeten? Håller sig p99-latensen inom samma band som kontrollgruppen? Bränner felbudgeten snabbare än baslinjen?
Om inget av dessa frågor är instrumenterade är utrullningsschemat en tidslinje, inte en valideringsloop.
En konfiguration som håller i produktion: definiera två SLO-utvärderingsfönster. Ett kort fönster (15 minuter) fångar snabba fel: en dålig databasfråga, ett schemamissmatch, en regression i en kritisk sökväg. Ett längre fönster (24 timmar eller en full trafikcykel) fångar gradvis försämring: minneläckor, cachetryck, kantfall i lågfrekvent trafik. Kräv att båda fönstren visar grönt innan du avancerar. Om något fönster överträds, stoppa utrullningen och larma on-call.
Procentratten är ett reglage. SLO-fönstret är grinden. Båda krävs.
Kill switch-konstruktion: designa den innan du behöver den
Kill switchen är inte en reservlösning. Den är ett förstaklassbeslut i designen som ska finnas innan den första kodraden för funktionen skrivs.
En kill switch designad under press är en kill switch med oprövade antaganden. Du testar den för första gången under en aktiv incident, i en terminalsession öppnad från en PagerDuty-notis, med fem personer som bevakar en Slack-tråd. Det är det sämsta möjliga ögonblicket att upptäcka att din ops-flagga riktar in sig på användare via sessions-ID och att din sessionstjänst för tillfället är degraderad.

Tre egenskaper som inte går att kompromissa med för en kill switch avsedd för produktionsbruk:
Sub-50ms lokal utvärdering: flaggkontrollern kan inte vara ett nätverksanrop till en fjärrutvärderingstjänst. Om utvärderingen beror på en tjänst som själv kan vara degraderad har du ett cirkulärt beroende i din incidentrespons.
Explicit fallback-värde: vad returnerar flaggan när flaggtjänsten inte är nåbar? Detta måste dokumenteras, definieras i kod, och testas. "Vad SDK:n defaultar till" är inte ett svar.
Testad under beroendefel: kill switches ska ingå i din chaos engineering-rotation. Validera dem mot scenarier där auth är degraderad, där flaggtjänsten själv är nere, och där nätverksfördröjningen till utvärderingsendpointen överstiger 2 sekunder.
Team som hanterar incidentrespons väl är de som repeterat. Kill switchen är en del av runbook:en. Gör det tråkigt.
Flaggskuld: teknisk skuld som ingen sätter på roadmap:en
Team som adopterar feature flags aggressivt samlar ofta på sig vad som ibland kallas flaggskuld: flaggor som fullföljde sitt syfte men aldrig togs bort. Funktionen shippades, experimentet avslutades, betatestningen avslutades. Flaggan stannade.
Vid 50 flaggor är detta en liten olägenhet. Vid 500 flaggor i ett distribuerat system är det en aktiv operativ risk. Varje flagga är en kodgren som kräver underhåll, testning och förståelse under incidentutredning. En utvecklare som försöker förstå ett fel klockan 2 på natten vill inte spåra igenom 40 villkorliga grenar för att hitta den relevanta.
Ett mönster observerat bland flera plattformsteam: flaggutvärderingsmiddleware som dyker upp bland de fem toppstackramarna för p99-latens. Orsaken i de flesta fall är inaktuella flaggor med komplexa inriktningsregler som utvärderar dussintals villkor per request, bärande tyngden av beslut fattade för två år sedan som ingen kände sig bekväm med att ta bort.
Motåtgärden är organisatorisk snarare än teknisk. Varje flagga som skapas ska ha tre attribut: en ägare, en typ (release, experiment, ops, behörighet) och ett förväntat borttagningsdatum. Release-flaggor ska tas bort inom två sprintar efter full utrullning. Experimentflaggor ska tas bort när experimentet avslutas, inte "när någon hinner med det." Flagginventeringen ska vara reviderbar på begäran och synlig i engineering health-dashboards.
Inriktningsgranularitet: dimensionen som brister vid enterprise-skala
De flesta feature flag-plattformar stöder procentbaserade utrullningar och grundläggande attributinriktning på användare. Det gap som uppstår vid enterprise-skala är inriktningsgranularitet: förmågan att uttrycka utrullningsregler som är tillräckligt specifika för att vara användbara utan att bli så komplexa att de är omöjliga att underhålla.
En användbar inriktningshierarki för produktionsutrullningar på plattformsteamnivå:
Miljönivå: produktion, staging, preview. Den första grinden, inte den enda.
Infrastruktursegment: datacenter, tillgänglighetszon eller Kubernetes-kluster. Användbart för att isolera geografiskt blast radius.
Konto eller tenant: för B2B SaaS-plattformar är det ofta säkrare att rulla ut per konto än per användarprocentandel, eftersom du kan observera ett fullt kontos trafikmönster snarare än ett statistiskt urval.
Användarkohort: betatestare, interna användare, avancerade användare per aktivitetsnivå.
Sessionsattribut: användbart för experimentflaggor, farligt för ops-flaggor.
Plattformarna som implementerar detta väl (LaunchDarkly och Statsig är de mest citerade av SRE-team som gör detta i skala) tillåter komplex regelkomposition utan att kräva ingenörstid för att modifiera inriktningslogiken under en aktiv utrullning. Den self-service-förmågan är skillnaden mellan en 30 sekunders paus i utrullningen och ett ärende till plattformsteamet.
Plattformarna som implementerar detta dåligt tvingar dig att välja mellan inriktningsgranularitet och operativ enkelhet. Det avvägningsbeslutet dyker upp klockan 3 på natten.
Vad post-mortemet alltid hittar
Varje post-mortem för en funktionsrelaterad produktionsincident ställer samma uppsättning frågor. Var funktionen gated bakom en flagga? Var utrullningen progressiv? Fanns det ett valideringsvillkor mellan stegen? Testades kill switchen innan incidenten?
Om alla fyra svar är ja är incidenten ett kalibreringsproblem: trösklar satta för löst, inriktningsregler med ett kantfall, SDK-utvärderingsbeteende under nätverkspartition som inte beaktades. Det går att lösa med konfigurationsändringar och runbook-uppdateringar.
Om något svar är nej är incidenten ett arkitekturproblem. Feature flags är inte ett felsökningsverktyg. De är ett beslut om deploymentarkitektur. Det beslutet antingen finns innan funktionen shippas, eller så finns det inte alls.
Frågan värd att besvara innan nästa release: vad skulle post-mortemet säga om den här utrullningen om något går fel i natt?