Wat is een feature flag? Gids in gewone taal voor solo devs
Samenvatting
Een feature flag is een voorwaarde in je code waarvan de waarde buiten de code wordt bepaald, zodat je een feature aan of uit kunt zetten zonder opnieuw te deployen. Zo scheid je deployen van vrijgeven, zodat je onafgewerkt werk dagelijks kunt mergen, geleidelijk uitrolt naar 1% van de gebruikers en een noodstop hebt. De keerzijde: elke flag voegt een codepad toe en moet na de uitrol weg. Solo devs hebben op dag één zelden een leverancier nodig.
Wat is een feature flag? Een if-statement waarvan het antwoord buiten je code ligt. Je zet de nieuwe codeweg uit en zet hem later aan door een waarde te wijzigen in een configuratiebestand, een databaserij of een flagdienst, zonder opnieuw te deployen. Die ene truc scheidt het deployen van code van het vrijgeven van een feature, en daarom is een flag de goedkoopste rollback die je ooit zult hebben.
Ik heb het tweede deel van die zin op de harde manier geleerd. Mijn eerste flag was een boolean in een environment variable, op een vrijdagavond omgezet, en ik was elf maanden vergeten dat hij bestond. Er brak niets. Dat is precies het probleem, en daar komen we nog op terug.
Hoe ziet een feature flag er in code eigenlijk uit?
Kleiner dan de homepages van de leveranciers doen vermoeden. Haal de dashboards weg en een flag is een opzoeking plus een vertakking:
const flags = { newCheckout: false };
if (flags.newCheckout) {
return renderNewCheckout(user);
}
return renderOldCheckout(user);Al de rest gaat over de vraag waar flags vandaan komt en wie hem mag wijzigen. Een constante in het bestand is een flag die je wijzigt door te deployen, en dat verslaat het hele doel. Een environment variable verandert bij een herstart. Een rij in je database verandert binnen seconden. Een gehoste dienst verandert ook binnen seconden, en geeft je daarnaast targeting per gebruiker, een UI en een audit log.
Waar het in de praktijk wringt: de code is triviaal, de levenscyclus niet. Twee takken in productie betekent twee gedragingen om te testen, twee paden om om twee uur 's nachts te debuggen, en één daarvan is gedoemd om te verrotten.

Welke vier soorten feature flags bestaan er, en welke heb je eerst nodig?
Martin Fowlers taxonomie van feature toggles is nog steeds de schoonste manier om ze te sorteren, en de nuttige as is hoe lang elk type zou moeten leven.
Release flags verbergen werk dat nog niet af is of riskant is. Ze zijn tijdelijk: een week of twee, dan verwijderen. Dit is degene die je het eerst nodig hebt.
Ops flags zijn noodstoppen. Je omhult een zware of fragiele feature, zoals een aanbevelingswidget of een externe API-call, zodat je die onder belasting kunt uitzetten zonder deploy. De meeste zijn kortlevend, een paar blijven voor altijd, en dat is prima.
Experiment flags verdelen gebruikers in cohorten voor A/B-tests. Ze leven zolang het duurt om een statistisch betekenisvol resultaat te halen, dus uren tot weken, en ze hebben echt verkeer nodig om iets te betekenen.
Permission flags bepalen per abonnement of account wie een feature ziet: de Pro-tier, de bètagroep. Die kunnen jaren meegaan, en op dat moment zijn het eigenlijk geen flags meer. Het zijn rechten, en die verdienen een goed datamodel.
Ben je een solo dev met 40 gebruikers, dan heb je release flags nodig en misschien één noodstop. Experiment flags op 40 gebruikers leveren ruis op, geen data. Sla ze over tot je de metric en de steekproefgrootte kunt benoemen.
Welk probleem lossen flags op dat branches en deploys niet oplossen?
Drie dingen, en alleen die drie zijn de moeite waard.
Onafgewerkt werk veilig uitleveren. Langlevende branches doen pijn, want mergen is een kleine oorlog. Met een flag merge je elke dag naar main terwijl de nieuwe code uit staat. Dit is de motor achter trunk-based development, waarbij iedereen op één branch commit en de flags de onafgemaakte delen dragen.
Geleidelijke uitrol. Zet de feature aan voor jezelf, dan voor 1% van de gebruikers, dan 10%, dan iedereen. Fowler beschrijft een canary-cohort van ongeveer 1% door een user-ID modulo 100 te nemen. Gaat er iets mis, dan is de schade een handvol mensen in plaats van je hele bestand.
Snel terugdraaien. Een deploy terugdraaien betekent een build, een pipeline en wat lef. Een flag omzetten is één wijziging. Op een slechte dag is het verschil minuten pijn tegenover een uur.
Niets hiervan heeft op dag één een leverancier nodig. Alles hiervan heeft wel discipline nodig.
Heb je LaunchDarkly nodig, of is een JSON-bestand prima?
Een JSON-bestand of een databasetabel is prima, totdat een van deze dingen waar wordt: een niet-developer moet flags kunnen omzetten, je hebt procentuele uitrol of targeting per gebruiker nodig, je wilt een audittrail van wie wat heeft gewijzigd, of je draait meerdere services die dezelfde flags lezen.
Dit is de ruwe ladder die ik zou beklimmen, in volgorde:
Constanten en environment variables. Nul kosten. Prima voor de eerste release flag van een side project.
Een
flags-tabel of een JSON-bestand dat je tijdens runtime leest. Tien regels code, directe wijzigingen, geen leverancier. Hiermee komt een solo project verrassend ver.Een open-source of gehoste flagdienst. Als je targetingregels, geleidelijke uitrol en een UI wilt die iemand anders kan gebruiken.
Een enterprise-platform. Als compliance, goedkeuringen en tientallen engineers in beeld komen.
Gehoste tools dekken stap 3 en 4. LaunchDarkly is de gevestigde naam, met de diepste targeting- en governancefuncties en een prijs die dat weerspiegelt.
Statsig bundelt flags met experimenten en productanalyse. Dat is logisch als je wilt meten wat de flag deed, en niet alleen wilt schakelen.
Sla beide over als je hele team uit jou bestaat. Een tabel met drie kolommen wint het van een dashboard dat je twee keer per kwartaal opent. Kies pas een dienst als de handmatige versie je iets specifieks heeft gekost, zoals een late bewerking van de productieconfiguratie waar je spijt van kreeg.
Een verzekering die het weten waard is: OpenFeature is een CNCF-incubating project dat een leveranciersneutrale API definieert om flags te evalueren, met SDK's voor Node.js, Python, Go, Java, .NET en web-clients, onder andere. Je codeert tegen de standaardinterface en wisselt de provider eronder. Verwacht je dat je opzet je ontgroeit, dan maakt het lopen via OpenFeature die verhuizing tot een configuratiewijziging.

Hoe voeg je je eerste flag toe zonder een rommeltje te maken?
Begin met één release flag en een paar basisregels. Dit is de versie die ik had moeten volgen.
Noem hem naar de feature, niet naar het mechanisme. new-checkout-flow vertelt je wat er breekt als hij fout is. flag_47 vertelt je over zes maanden niets.
Standaard uit, en uit betekent het oude gedrag. De conventie "uit is legacy, aan is nieuw" laat je het systeem onder druk doorgronden. Breek je die, dan wordt elke flag een puzzel.
Evalueer op één plek. Fowler noemt de oplossing toggle inversion: in plaats van if (flags.x) over twintig bestanden te strooien, beslis je één keer, dicht bij de rand van het systeem, en geef je het resultaat door. Eén beslispunt betekent één plek om te wijzigen en één plek om te testen.
Schrijf het verwijderticket op het moment dat je de flag aanmaakt. Zet het in de backlog met een datum. Fowler stelt ook vervaldatums voor kortlevende toggles voor, en zelfs tests die falen zodra een flag zijn datum voorbij is. Een flag zonder verwijderticket is een lening zonder aflossingsschema.
Log elke evaluatie die ertoe doet. Als een gebruiker een bug meldt, wil je weten aan welke kant van de flag hij zat. Kun je dat niet beantwoorden, dan is de flag een risico.
Testen is waar mensen overengineeren. Je hoeft niet elke combinatie van flags te testen, want de meeste flags werken niet op elkaar in. Test de configuratie die je in productie verwacht, test de fallback met de nieuwe flag uit, en draai eventueel één keer alles aan om afwijkingen op te sporen.
Wat is de echte prijs van feature flags waar niemand het over heeft?
Elke flag verdubbelt een codepad. Tien onafhankelijke flags zijn in theorie 1.024 combinaties. Hoewel je ze nooit allemaal test, kun je er in productie toch een tegenkomen die niemand voorzag.
De pijnlijkere kost zijn dode flags. De uitrol is klaar, iedereen heeft het nieuwe gedrag, de flag blijft op 100% staan en de oude tak zit in de repo als code die niemand durft te verwijderen. Zes maanden later weet niemand meer of uitzetten veilig is.
De beroemde versie hiervan is Knight Capital in augustus 2012. Een oude flag die ooit een uitgefaseerde handelsfunctie activeerde, werd hergebruikt voor nieuwe code. Een van de acht servers miste de uitrol en draaide nog de oude code. In 45 minuten verloor het bedrijf volgens het eigen kwartaalrapport ongeveer $440 miljoen. Latere berichten brengen het bedrag dichter bij $460 miljoen. Dat is een handelsbedrijf met echt geld en echte engineers, dus ik ga niet beweren dat je side project veiliger is. De les schaalt prima naar beneden: hergebruik nooit een flagnaam, en verwijder dode flags voordat ze archeologie worden.

Fowlers kader is het kader dat ik blijf gebruiken: behandel flags als voorraad met een kostprijs. Sommige teams beperken het aantal actieve flags en eisen dat je er één verwijdert voordat je er een toevoegt. Voor een solo dev is een harde limiet van vijf ruim genoeg.
Wanneer sla je feature flags helemaal over?
Vaker dan de tooling-leveranciers toegeven.
Sla ze over als de feature klein is, de wijziging makkelijk terug te draaien is in git en je deploy twee minuten duurt. Een flag voegt een tak toe, een configuratiebron en een ding om te vergeten. Is een revert sneller dan een flag omzetten, dan is de flag theater.
Sla ze over als je nog geen gebruikers hebt. Geleidelijke uitrol naar nul mensen is gewoon uitstel. Shippen, naar de logs kijken, repareren.
Sla ze over voor databasemigraties die je niet met een schakelaar ongedaan kunt maken. Een flag kan een nieuwe kolom in de UI verbergen, maar hij kan een tabel niet terughalen. Schemawijzigingen hebben een eigen expand-and-contract-plan nodig, met of zonder flags.
Het loont wel wanneer de wijziging betalingen of authenticatie raakt, wanneer je dagelijks wilt mergen met onafgewerkt werk, of wanneer een externe afhankelijkheid kan falen en je een noodstop wilt.
Waar moet je op letten zodra een flag live staat?
Een flag regelt blootstelling, en blootstelling helpt alleen als je ziet wat daarna gebeurt. Een feature aanzetten voor 10% van de gebruikers zonder foutpercentages en latency in de gaten te houden, is een muntopgooi met extra stappen.
Zorg vóór de eerste uitrol dat je drie vragen in minder dan een minuut kunt beantwoorden: zijn er meer fouten in het geflagde cohort, is de latency slechter, en is er iets stroomafwaarts veranderd? Uptimemonitoring en logzoeken dekken het grootste deel hiervan voor een klein product. Een tool als Better Stack zet monitors, statuspagina's en logs op één plek, met een gratis laag.
Dit is de regel die ik nu volg: een flag is maar zo goed als het alarm dat eraan hangt. Zonder alarm zet je dingen in het donker aan.
Wat zouden we deze week echt doen?
Kies één onafgewerkt ding waar je bang voor bent om het te mergen. Zet het achter een boolean die uit een tabel of JSON-bestand wordt gelezen, standaard uit, en merge het vandaag naar main. Schrijf het verwijderticket voordat je de editor sluit, met een datum over twee weken.
Zet het daarna alleen voor jezelf aan en gebruik het een dag. Houdt het stand, dan breid je uit. Zo niet, dan zet je het uit, en heb je niets verloren dan een minuut.
Welke flag in je codebase staat nu al meer dan een maand op 100%? Die is je eerste verwijdering.