Cos'è un feature flag? Guida semplice per il dev solo
Riassunto
Un feature flag (o feature toggle) è un condizionale nel codice il cui valore è controllato fuori dal codice, così puoi accendere o spegnere una funzione senza rifare il deploy. Separa il deploy dal rilascio. Permette merge quotidiani di lavoro incompleto, rollout graduali verso l'1% degli utenti e kill switch istantanei. Il rovescio della medaglia: ogni flag aggiunge un percorso di codice e va eliminato dopo il rollout. Un dev solo raramente ha bisogno di un fornitore il primo giorno.
Cos'è un feature flag? Un if la cui risposta vive fuori dal tuo codice. Spedisci il nuovo percorso di codice spento, poi lo accendi più tardi cambiando un valore in un file di configurazione, in una riga del database o in un servizio di flag, senza nessun redeploy. Questo trucco separa il deploy del codice dal rilascio di una funzione, ed è il motivo per cui un flag è il rollback più economico che avrai mai.
Ho imparato la seconda metà di quella frase nel modo difficile. Il mio primo flag era un booleano in una variabile d'ambiente, acceso un venerdì sera, e me ne sono dimenticato per undici mesi. Non si è rotto niente. Ed è proprio questo il problema, ci arriviamo.
Come appare un feature flag nel codice?
Più piccolo di quanto suggeriscano le homepage dei vendor. Togli le dashboard e un flag è una lettura più un branch:
const flags = { newCheckout: false };
if (flags.newCheckout) {
return renderNewCheckout(user);
}
return renderOldCheckout(user);Tutto il resto è una domanda su da dove arriva flags e su chi può cambiarlo. Una costante nel file è un flag che cambi con un deploy, quindi vanifica lo scopo. Una variabile d'ambiente cambia al riavvio. Una riga nel database cambia in pochi secondi. Un servizio ospitato cambia in pochi secondi e in più ti dà il targeting per utente, un'interfaccia e un log di audit.
Il problema vero, in pratica, è questo: il codice è banale, il ciclo di vita no. Due branch in produzione significano due comportamenti da testare, due percorsi da debuggare alle 2 di notte, e uno dei due è destinato a marcire.

Quali sono i quattro tipi di feature flag e da quale iniziare?
La tassonomia dei feature toggle di Martin Fowler è ancora il modo più pulito per ordinarli, e l'asse utile è per quanto tempo ciascun tipo dovrebbe vivere.
Release flag nascondono lavoro incompleto o rischioso. Sono transitori: una o due settimane, poi si cancellano. È quello che ti serve per primo.
Ops flag sono kill switch. Avvolgi una funzionalità pesante o fragile (un widget di raccomandazioni, una chiamata a un servizio esterno) così puoi spegnerla sotto carico senza deploy. La maggior parte è di breve durata, alcuni restano per sempre e va bene così.
Experiment flag dividono gli utenti in coorti per i test A/B. Vivono quanto serve per ottenere un risultato statisticamente significativo, quindi da ore a settimane, e hanno bisogno di traffico reale per avere senso.
Permission flag limitano le funzioni per piano o per account: il tier Pro, il gruppo beta. Possono durare anni, e a quel punto non sono davvero più flag. Sono diritti di accesso e meritano un modello dati vero.
Se sei un dev solo con 40 utenti, ti servono release flag e forse un kill switch. Gli experiment flag su 40 utenti producono rumore, non dati. Aspetta finché non sai nominare la metrica e la dimensione del campione.
Quale problema risolvono i flag che branch e deploy non risolvono?
Tre cose, e solo tre meritano attenzione.
Spedire lavoro incompleto in sicurezza. I branch che restano aperti a lungo fanno male, perché il merge diventa una piccola guerra. Un flag ti permette di fare merge su main ogni giorno con il nuovo codice spento. È il motore dello sviluppo trunk-based, dove tutti committano su un solo branch e i flag portano le parti incomplete.
Rollout graduale. Accendi la funzione per te, poi per l'1% degli utenti, poi per il 10%, poi per tutti. Fowler descrive la scelta di una coorte canary di circa l'1% prendendo l'ID utente modulo 100. Se qualcosa va storto, il raggio d'impatto sono poche persone invece di tutta la tua base.
Annullare in fretta. Fare rollback di un deploy significa una build, una pipeline e un po' di coraggio. Girare un flag significa una modifica. Nelle giornate storte la differenza è tra qualche minuto di dolore e un'ora.
Niente di tutto questo richiede un fornitore il primo giorno. Tutto richiede disciplina.
Ti serve LaunchDarkly, o un file JSON basta?
Un file JSON o una tabella di database va bene finché non si verifica una di queste condizioni: un non-sviluppatore deve poter girare i flag, ti servono rollout in percentuale o targeting per utente, ti serve una traccia di chi ha cambiato cosa, oppure più servizi leggono gli stessi flag.
Ecco la scala approssimativa che salirei, in ordine:
Costanti e variabili d'ambiente. Costo zero. Va bene per il primo release flag di un side project.
Una tabella
flagso un file JSON letto a runtime. Dieci righe di codice, toggle istantanei, nessun fornitore. Questo porta un progetto solo parecchio lontano.Un servizio di flag open source o ospitato. Quando vuoi regole di targeting, rollout graduali e un'interfaccia che può usare qualcun altro.
Una piattaforma enterprise. Quando entrano in gioco compliance, approvazioni e decine di ingegneri.
I servizi ospitati coprono i passi 3 e 4. LaunchDarkly è il riferimento storico, con il targeting e la governance più profondi e un prezzo che lo riflette.
Statsig unisce flag, esperimenti e analytics di prodotto, ed è sensato se hai intenzione di misurare cosa ha fatto il flag, non solo di accenderlo e spegnerlo.
Salta entrambi se la tua squadra sei tu. Una tabella con tre colonne batte una dashboard che apri due volte a trimestre. Scegli un servizio solo quando la versione manuale ti è costata qualcosa di preciso, tipo una modifica notturna alla config di produzione di cui poi ti sei pentito.
Un'assicurazione da conoscere: OpenFeature è un progetto CNCF in incubazione che definisce un'API neutrale rispetto ai fornitori per valutare i flag, con SDK per Node.js, Python, Go, Java, .NET e client web, tra gli altri. Programmi contro l'interfaccia standard e cambi il provider sotto. Se sospetti che il tuo primo setup ti starà stretto, passare da OpenFeature trasforma quel cambio in una modifica di configurazione.

Come aggiungi il primo flag senza fare disastri?
Parti da un singolo release flag e da qualche regola base. È la versione che avrei voluto seguire io.
Dagli il nome della funzione, non del meccanismo. new-checkout-flow ti dice cosa si rompe se è sbagliato. flag_47 non ti dice niente tra sei mesi.
Parti da spento, e fa' in modo che spento significhi comportamento vecchio. La convenzione "spento uguale legacy, acceso uguale nuovo" è ciò che ti permette di ragionare sul sistema sotto pressione. Se la rompi, ogni flag diventa un puzzle.
Valuta in un solo punto. Fowler chiama la soluzione inversione del toggle: invece di spargere if (flags.x) in venti file, decidi una volta, vicino al bordo del sistema, e passi il risultato dentro. Un solo punto di decisione significa un solo posto dove cambiare e un solo posto dove testare.
Scrivi il ticket di rimozione nel momento in cui crei il flag. Mettilo nel backlog con una data. Fowler suggerisce anche date di scadenza sui toggle di breve durata, e perfino test che falliscono quando un flag supera la sua data. Un flag senza ticket di rimozione è un prestito senza piano di rimborso.
Logga ogni valutazione che conta. Quando un utente segnala un bug, vuoi sapere da quale lato del flag si trovava. Se non puoi rispondere, il flag è un passivo.
Sui test è dove la gente esagera. Non serve testare ogni combinazione di flag, perché la maggior parte non interagisce con le altre. Testa la configurazione che ti aspetti in produzione, testa il fallback con il flag spento, e facoltativamente fai un passaggio con tutto acceso per intercettare la deriva.
Qual è il costo reale dei feature flag di cui nessuno parla?
Ogni flag raddoppia un percorso di codice. Dieci flag indipendenti sono, in teoria, 1.024 combinazioni, e anche se non le testerai mai tutte, in produzione potresti incappare in una che nessuno aveva previsto.
Il costo più doloroso sono i flag morti. Il rollout finisce, tutti sono sul nuovo comportamento, il flag resta al 100%, e il ramo vecchio resta nel repo come codice che nessuno osa cancellare. Sei mesi dopo nessuno ricorda se spegnerlo sia sicuro.
La versione famosa di questo è Knight Capital, agosto 2012. Un vecchio flag che un tempo attivava una funzione di trading ritirata è stato riutilizzato per codice nuovo. Uno degli otto server non ha ricevuto il deploy e girava ancora il codice vecchio. In 45 minuti la società ha perso circa $440 milioni secondo il proprio 10-Q trimestrale, cifra che report successivi portano vicino a $460 milioni. Quella è una società di trading con soldi veri e ingegneri veri, quindi non ti dirò che il tuo side project è più sicuro. La lezione si scala giù bene: non riutilizzare mai un nome di flag, e cancella i flag morti prima che diventino archeologia.

La cornice di Fowler è quella che tengo a mente: tratta i flag come inventario con un costo di mantenimento. Alcuni team limitano il numero di flag attivi e chiedono di rimuoverne uno prima di aggiungerne un altro. Per un dev solo, un tetto fisso di cinque basta e avanza.
Quando conviene saltare del tutto i feature flag?
Più spesso di quanto ammettano i vendor.
Saltali quando la funzione è piccola, la modifica si annulla facilmente con git e il deploy richiede due minuti. Un flag aggiunge un branch, una fonte di configurazione e una cosa da dimenticare. Se un revert è più veloce di un flip del flag, il flag è teatro.
Saltali quando non hai ancora utenti. Un rollout graduale verso zero persone è solo un ritardo. Spedisci, guarda i log, correggi.
Saltali per le migrazioni di database che un toggle non può annullare. Un flag può nascondere una nuova colonna nell'interfaccia, ma non può ripristinare una tabella cancellata. Le modifiche allo schema richiedono un piano expand-and-contract tutto loro, con o senza flag.
Vale la pena quando la modifica tocca pagamenti o autenticazione, quando vuoi fare merge ogni giorno con lavoro incompleto, o quando una dipendenza esterna potrebbe cadere e vuoi un kill switch.
Cosa tenere d'occhio con un flag attivo, e cosa fare già questa settimana
Un flag controlla l'esposizione, e l'esposizione serve solo se vedi cosa succede dopo. Accendere una funzione per il 10% degli utenti senza guardare tassi di errore e latenza è testa o croce con qualche passaggio in più.
Prima del primo rollout, assicurati di poter rispondere a tre domande in meno di un minuto: sono aumentati gli errori nella coorte con il flag, la latenza è peggiorata, è cambiato qualcosa a valle? Il monitoraggio di uptime e la ricerca nei log coprono gran parte del problema per un prodotto piccolo, e uno strumento come Better Stack mette monitor, status page e log in un solo posto, con un piano gratuito.
La regola che seguo ora: un flag vale quanto l'allarme collegato. Senza, stai accendendo cose al buio.
Quindi questa settimana: scegli una cosa incompleta che hai paura di fare merge. Mettila dietro un booleano letto da una tabella o da un file JSON, di default spento, e fanne merge su main oggi stesso. Scrivi il ticket di rimozione prima di chiudere l'editor, con una data tra due settimane.
Poi accendila solo per te e usala per un giorno. Se regge, allargala. Se no, spegnila: hai perso solo un minuto.
In quale flag del tuo codice l'interruttore è al 100% da più di un mese? Quella è la tua prima cancellazione.