Eu lembro exatamente do dia em que percebi que estávamos confundindo deploy com release.
Era uma sexta-feira à tarde (clássico). Tínhamos desenvolvido uma nova funcionalidade importante para o produto. O código já estava revisado, testado, aprovado em QA. A pressão era grande para colocar em produção. Fizemos o deploy.
Minutos depois, começaram os problemas.
A feature ainda não estava 100% validada para todos os cenários. Alguns usuários começaram a relatar comportamentos estranhos. O rollback virou a única saída. E, como quase sempre acontece, rollback nunca é tão simples quanto parece — banco já migrado, outras mudanças incluídas no mesmo pacote, pequenas dependências que ninguém lembra até dar errado.
Naquele momento ficou claro para mim: o problema não era a qualidade da feature. Era a forma como estávamos entregando.
Estávamos presos ao modelo “tudo ou nada”. Ou a funcionalidade ia para todos os usuários, ou não ia para ninguém. Não existia meio termo. Não existia controle fino. Não existia uma forma segura de testar em produção com impacto limitado.
Foi aí que comecei a estudar mais profundamente sobre Feature Flags.
A ideia parecia simples demais para resolver um problema tão grande: colocar uma camada de controle entre o código que está em produção e a liberação real da funcionalidade para os usuários.
Mas quanto mais eu estudava — e principalmente quando comecei a aplicar — mais percebi que Feature Flags não são apenas um detalhe técnico. Elas mudam a forma como você pensa deploy, release, risco e até experimentação de produto.
Neste artigo, quero compartilhar o que aprendi sobre Feature Flags, por que elas são tão poderosas e também quais cuidados são necessários para não transformar essa solução em um novo problema.
O que são Feature Flags (de forma prática)
Depois daquele episódio, eu comecei a buscar uma forma de separar uma coisa da outra: colocar código em produção e liberar a funcionalidade para os usuários.
Foi aí que entendi, de forma prática, o que são Feature Flags.
De maneira simples, uma Feature Flag é um mecanismo que permite ativar ou desativar uma funcionalidade em tempo de execução, sem precisar fazer um novo deploy.
Na prática, é como colocar um interruptor dentro do seu código.
Em vez de assumir que, se o código está em produção, a feature está automaticamente ativa para todos, você adiciona uma camada de controle:
Nesse exemplo simples, a nova dashboard já está deployada. O código está em produção. Mas quem decide se ela aparece ou não para o usuário é a flag.Isso muda completamente o jogo.
Com Feature Flags, você pode:
- Fazer deploy de uma funcionalidade inacabada (desde que protegida por uma flag)
- Liberar apenas para usuários internos
- Ativar para 5% da base
- Desativar imediatamente caso algo dê errado
Ou seja: deploy deixa de ser um momento de tensão e passa a ser apenas uma etapa técnica.
A decisão de negócio — quando liberar, para quem liberar e em que ritmo liberar — passa a ser controlada separadamente.
Na essência, Feature Flags são isso:
Uma forma de desacoplar o ato de entregar código do ato de expor uma funcionalidade ao usuário.
Simples na teoria. Transformador na prática.
Tipos de Feature Flags (visão rápida)
Nem toda Feature Flag serve para o mesmo propósito. Com o tempo, percebi que classificá-las ajuda muito a usá-las com mais consciência — e evitar bagunça no código.
Aqui estão os principais tipos, de forma direta:
1️⃣ Release Toggles
São as mais comuns.
Servem para liberar funcionalidades gradualmente.
Você faz o deploy da feature, mas controla quando ela será ativada — seja para todos, para um grupo específico ou de forma progressiva.
É o tipo que resolve o problema clássico de “deploy ≠ release”.
2️⃣ Experiment Toggles
Usadas para testes A/B e experimentação.
Permitem expor versões diferentes da mesma funcionalidade para grupos distintos de usuários, medindo impacto em métricas como conversão, retenção ou engajamento.
Aqui, a flag deixa de ser apenas técnica e passa a ser ferramenta de produto.
3️⃣ Ops Toggles
São flags operacionais.
Servem para controlar comportamentos críticos em runtime, como:
- Desativar uma integração externa
- Reduzir consumo de um serviço
- Ativar um modo de contingência
Essas são especialmente úteis em momentos de incidente.
Deploy não é Release
Se tem algo que Feature Flags mudaram para mim, foi a forma como eu enxergo risco.
Antes, cada deploy vinha acompanhado de tensão. Mesmo mudanças pequenas pareciam maiores do que realmente eram, porque assim que algo chegava em produção, estava automaticamente exposto para todos os usuários. Não existia rede de segurança — apenas confiança e expectativa de que tudo daria certo.
Feature Flags trouxeram controle.
Elas me permitiram subir código antes, testar em ambiente real com um grupo reduzido de usuários e reagir rapidamente caso algo não se comportasse como esperado. Mais do que isso, ajudaram a separar entrega técnica de decisão de negócio. A engenharia pode fazer deploy contínuo, enquanto produto decide quando e como liberar.
Mas existe um ponto importante: Feature Flags exigem disciplina.
Se você não remove flags antigas, não documenta o propósito delas e não define responsabilidade, elas rapidamente se transformam em dívida técnica invisível.
Quando bem utilizadas, porém, representam um salto de maturidade na engenharia. Incentivam entregas progressivas, experimentação com segurança e sistemas mais resilientes.
Hoje, eu não enxergo Feature Flags apenas como um if no código.
Eu enxergo como uma decisão arquitetural — uma que permite que times avancem com mais confiança, sem precisar escolher entre velocidade e estabilidade.