Il deploy è quando il codice arriva in produzione. Il rilascio è quando qualcuno può davvero usarlo. Confondere le due cose è uno dei modi più veloci per rendere ogni deploy un piccolo momento di tensione.
I feature flag servono a mettere spazio tra questi due momenti. Puoi deployare oggi, accendere domani per il team interno, poi per un cliente pilota, poi per il 10% degli utenti. Se qualcosa va male, spegni il flag. Non devi per forza fare rollback di tutta la release.
Il flag non è solo un if
Tecnicamente spesso è un if. Culturalmente è molto di più.
if (await flags.isEnabled('checkout.v2.enabled', context)) { return newCheckout(input); } return oldCheckout(input);
Quel piccolo if può rappresentare un rollout graduale, un esperimento, una migrazione, un permesso enterprise o un kill switch operativo. Il problema è che, se non lo gestisci bene, può diventare anche debito tecnico che resta nel codice per due anni.
Dove entra OpenFeature
OpenFeature è una specifica aperta per valutare feature flag con una API comune. L'idea è semplice: il codice applicativo non dovrebbe dipendere direttamente dal vendor o dal sistema interno che usi per i flag.
L'app chiede:
const enabled = await client.getBooleanValue('checkout.v2.enabled', false, { targetingKey: user.id, plan: user.plan, country: user.country, });
Il provider decide da dove arrivano le regole: SaaS, file, servizio interno, flagd, configurazione GitOps. Se un giorno cambi backend di feature flagging, l'applicazione non deve essere riscritta ovunque.
Questa separazione sembra un dettaglio architetturale, ma si sente quando il progetto cresce.
Il contesto è metà del lavoro
Un flag acceso o spento per tutti è utile, ma limitato. La progressive delivery vive nel contesto:
- utente interno o esterno;
- piano free o enterprise;
- paese;
- organizzazione;
- versione dell'app;
- percentuale stabile di traffico.
La chiave importante è targetingKey: deve essere stabile. Se cambia a ogni request, un utente può finire una volta nella variante A e una volta nella variante B. Per un esperimento è pessimo, per un checkout può essere disastroso.
Un rollout sensato
Un flusso che mi piace è questo:
- deploy con flag spento;
- accensione per sviluppatori e QA;
- accensione per un cliente o un tenant pilota;
- rollout al 5%;
- rollout al 25%;
- rollout al 100%;
- rimozione del vecchio codice e del flag.
Il punto spesso dimenticato è l'ultimo. Un flag temporaneo deve avere una data di morte. Se resta per sempre, ogni refactor futuro dovrà chiedersi: "ma questo ramo serve ancora?".
Kill switch: prepararli prima
Il kill switch è il flag che ti salva quando una dipendenza esterna inizia a fare scherzi, un job consuma troppe risorse o una nuova logica produce errori strani.
Un buon kill switch deve essere:
- facile da trovare;
- documentato nel runbook;
- testato ogni tanto;
- osservabile quando viene attivato;
- indipendente, per quanto possibile, dalla parte che potrebbe rompersi.
La cosa peggiore è scoprire durante l'incidente che il flag esiste, ma nessuno sa se funziona ancora.
Osservabilità o non è progressive delivery
Accendere una feature al 10% senza guardare metriche è solo ottimismo con più passaggi.
Ogni rollout dovrebbe rispondere a domande semplici:
- gli errori sono aumentati?
- la latenza è cambiata?
- gli utenti completano il flusso?
- ci sono più ticket o retry?
- una variante impatta solo un segmento?
OpenFeature supporta hook attorno alla valutazione dei flag. Sono utili per loggare errori, aggiungere metriche o collegare la valutazione a una trace.
Naming e ownership
I nomi contano. new_ui non dice nulla. checkout.v2.enabled dice molto di più.
Per ogni flag segnerei almeno:
- nome;
- descrizione;
- owner;
- default sicuro;
- motivo per cui esiste;
- data o condizione di rimozione.
Un flag senza owner è quasi sempre un flag che nessuno cancellerà.
Dove valutarli
Frontend, backend o edge? Dipende.
Se il flag riguarda layout, copy o onboarding, il frontend va bene. Se riguarda permessi, billing, limiti o dati sensibili, deve stare sul backend. Se riguarda routing o esperimenti ad alto traffico, l'edge può avere senso.
La regola semplice: il frontend può migliorare l'esperienza, ma non deve essere l'unica barriera di sicurezza.
Conclusione
I feature flag fatti bene cambiano il rapporto con la produzione. Non eliminano il rischio, ma lo rendono più piccolo e gestibile. Puoi rilasciare a fette, osservare, fermarti, tornare indietro, imparare.
OpenFeature aggiunge una base pulita: una API comune, provider intercambiabili e un modo più ordinato di far crescere il sistema. Però la disciplina resta tua: default sicuri, nomi chiari, metriche, owner e pulizia.
Il flag migliore è quello che ti aiuta a rilasciare con calma e poi sparisce quando non serve più.