Feature Flag é uma técnica de desenvolvimento em que a funcionalidade do aplicativo é ativada ou desativada por meio de chaves condicionais em tempo de execução, sem implantar novo código. Em vez da abordagem tradicional “commit — deploy”, os feature flags permitem separar o momento da implantação do momento da ativação da funcionalidade. De acordo com a LaunchDarkly (2024), as equipes que usam feature flags reduzem o tempo de lançamento de novos recursos em 40%. Os Feature flags tornaram-se um elemento essencial de CI/CD para aplicativos móveis e web modernos.
Principais pontos
Feature Flag (feature toggle) é um mecanismo que permite alterar o comportamento do aplicativo sem modificar o código. Na sua forma mais simples, é uma construção condicional que verifica o valor do flag antes de executar uma nova funcionalidade. O flag pode ser armazenado em um arquivo de configuração, banco de dados ou serviço externo e alterado em tempo real. Essa abordagem dá às equipes a capacidade de enviar código inacabado para o branch principal sem medo de que ele chegue aos usuários antes da conclusão do desenvolvimento.
O principal propósito dos feature flags é separar a implantação do lançamento. A implantação é o processo de colocar o código em um servidor ou loja de aplicativos. O lançamento é o momento em que a funcionalidade se torna disponível para o usuário. Sem feature flags, esses eventos coincidem: o código vai para produção — os usuários o veem. Com feature flags, o código pode ser implantado em produção semanas antes do lançamento, ativado para testes internos ou gradualmente distribuído para o público. Isso é crítico para o trunk-based development e a entrega contínua.
Considere uma implementação básica de feature flag em um aplicativo móvel em Kotlin. O flag é armazenado no Firebase Remote Config e carregado quando o aplicativo inicia. Dependendo do valor do flag, a tela de perfil antiga ou nova é exibida. Essa implementação permite lançar uma nova versão do perfil sem publicar uma atualização na App Store — basta alterar o valor no console do Firebase.
class ProfileFeature {
private val flags = FeatureFlagProvider()
private val profileFlag = FlagKey("new_profile_enabled")
fun getProfileScreen(): Screen {
return if (flags.isEnabled(profileFlag)) {
NewProfileScreen()
} else {
LegacyProfileScreen()
}
}
}
class FeatureFlagProvider {
fun isEnabled(key: FlagKey): Boolean {
val raw = Firebase.remoteConfig.getString(key.name)
return raw.toBoolean()
}
}
Nem todos os feature flags são iguais. A classificação de Martin Fowler identifica quatro tipos de flags, que diferem em propósito de uso, duração e requisitos de gerenciamento. A classificação adequada de flags ajuda a escolher a infraestrutura certa e evitar problemas comuns.
Os Release toggles são o tipo mais comum de flags. Eles são usados para ocultar funcionalidades incompletas em produção. O desenvolvedor envia código para o branch principal envolto em um flag e completa gradualmente a funcionalidade. Após a conclusão e os testes, o flag é ativado para todos os usuários. O ciclo de vida desse flag varia de alguns dias a duas semanas. Após a implantação completa, o flag é removido do código. Os Release toggles são a base do trunk-based development.
Os Experiment toggles funcionam em conjunto com testes A/B. Eles não apenas ativam ou desativam funcionalidades, mas direcionam o usuário para um dos grupos experimentais. Esses flags geralmente suportam regras de segmentação complexas (por região, versão do SO, assinatura) e integração com sistemas de análise. Os Ops toggles são usados para controle operacional — por exemplo, desativar uma função pesada sob alta carga ou desligar temporariamente um módulo problemático sem implantação imediata. Os Ops toggles devem ser o mais rápidos e confiáveis possível, pois a estabilidade do serviço depende deles.
| Tipo | Duração | Dinâmica | Propósito |
|---|---|---|---|
| Release | Dias-semanas | Estático | Ocultar código incompleto |
| Experiment | Dias-meses | Dinâmico | Testes A/B e rollout |
| Ops | Horas-dias | Dinâmico | Controle operacional |
| Permission | Meses+ | Estático | Controle de acesso |
O gerenciamento de feature flags é uma disciplina separada que inclui armazenamento, configuração, monitoramento e auditoria de flags. Sem um sistema de gerenciamento, os flags se transformam em dívida técnica incontrolável que retarda o desenvolvimento. Vamos examinar os principais aspectos do gerenciamento usando um sistema de produção como exemplo.
Cada feature flag passa por quatro estágios: criação, uso, estabilização e remoção. No estágio de criação, a chave do flag, o tipo e o valor padrão são definidos. Durante o uso, a equipe monitora quem ativou o flag, para qual público e com qual propósito. Após a estabilização (funcionalidade totalmente pronta e testada), o flag deve ser removido do código. O processo de remoção é automatizado por meio de revisão de código: o CI verifica se todos os flags ativados para 100% dos usuários têm uma tarefa de remoção.
Os feature flags devem ser armazenados centralizadamente, não dispersos em arquivos de configuração de cada serviço. Idealmente — um serviço dedicado com IU (LaunchDarkly, Unleash). Uma opção minimamente aceitável é um JSON de configuração no repositório com revisão de código para alterações. Um banco de dados para armazenar flags é menos preferível, pois requer uma interface de gerenciamento separada. Cada flag deve ter um proprietário (equipe ou desenvolvedor específico), uma descrição e um tempo de vida (TTL). A auditoria regular de flags obsoletos é uma prática obrigatória, automatizada por uma tarefa de CI que verifica flags inalterados por mais de N dias.
O mercado de ferramentas de gerenciamento de feature flags inclui tanto plataformas comerciais com ciclo de gerenciamento completo quanto soluções de código aberto para autoatendimento. A escolha da ferramenta depende do tamanho da equipe, dos requisitos de latência e da conformidade.
LaunchDarkly é a líder de mercado com SDKs para todas as linguagens e plataformas populares (iOS, Android, Web, Backend). Suporta multiambiente, segmentação baseada em regras, experimentos A/B e remoção automática de flags. Split é uma alternativa focada em recursos empresariais: acesso baseado em funções, logs de auditoria e conformidade (SOC2, HIPAA). ConfigCat é uma solução mais leve e acessível, adequada para equipes pequenas. Todas as plataformas fornecem SDKs com cache de valores e impacto mínimo na latência do aplicativo.
Unleash é a solução de código aberto mais popular com IU, API e SDKs para todas as principais plataformas. Suporta estratégias de ativação, contextos personalizados e integração com Prometheus para monitoramento. Flagsmith é uma alternativa com testes A/B integrados e gerenciamento de ambientes. As soluções de código aberto exigem implantação e manutenção de infraestrutura, mas fornecem controle total sobre os dados e não têm restrições de licenciamento. Para aplicativos móveis, ambas as soluções fornecem SDKs nativos com cache offline de valores de flags.
Feature flags são uma ferramenta poderosa, mas sem disciplina eles criam dívida técnica e complicam o código. Martin Fowler e os engenheiros da LaunchDarkly formularam um conjunto de práticas que ajudam a obter o máximo benefício dos feature flags sem consequências negativas. Vamos revisar as principais recomendações para sistemas de produção.
Cada feature flag que não foi removido após a conclusão do rollout se torna dívida técnica. Um estudo da LaunchDarkly (2024) mostrou que, em média, 30–40% dos flags permanecem no código depois de não serem mais necessários. Solução: implemente a regra “um flag — uma tarefa”. Ao criar um flag, uma tarefa de remoção com prazo é criada no rastreador de tarefas. O CI verifica se não há flags ativados em 100% por mais de 30 dias. A revisão de código deve verificar não apenas a adição, mas também a remoção de flags.
Feature flags criam complexidade combinatória para testes: cada flag dobra o número de estados possíveis do aplicativo. Para gerenciar essa complexidade, são usados testes matriciais que verificam todas as combinações de flags e testes de integração de alternância de flags. Uma etapa é adicionada ao pipeline de CI que executa testes com diferentes combinações de valores de flags. Para flags críticos (ops toggles), testes de carga são obrigatórios para verificar se a alternância do flag não causa picos de latência ou erros.
class FeatureFlagService:
def __init__(self, storage):
self.storage = storage
def is_enabled(self, flag_key, user_context):
flag = self.storage.get(flag_key)
if not flag:
return False
for rule in flag["rules"]:
if self._match_rule(rule, user_context):
return rule["value"]
return flag["default"]
def _match_rule(self, rule, context):
return (
rule["percentage"] > self._hash(context.user_id)
)
Perguntas frequentes
Os termos são frequentemente usados como sinônimos, mas há uma nuance: feature flag geralmente se refere a um sistema mais maduro com gerenciamento centralizado, IU e SDKs, enquanto feature toggle é uma simples chave binária no código. Martin Fowler usa feature toggle como termo geral, mas na indústria, feature flag é mais frequentemente associado a plataformas comerciais (LaunchDarkly, Split).
O impacto no desempenho é mínimo com a implementação adequada. Melhores práticas: armazenar em cache os valores dos flags na memória com TTL de 30–60 segundos, evitar chamadas HTTP síncronas ao verificar um flag, usar SDKs com cache local e sincronização em segundo plano. De acordo com a LaunchDarkly, a latência p99 do seu SDK é inferior a 5 ms, o que é insignificante para a maioria dos aplicativos.
Feature flags não são recomendados para alterar a lógica de negócios em operações financeiras críticas onde é importante saber exatamente qual código está sendo executado. Evite também flags para funções de segurança (autorização, criptografia) — desativar tal flag cria uma vulnerabilidade. Para mudanças de infraestrutura (migração de banco de dados, migração para nova arquitetura), feature flags são úteis, mas requerem testes especialmente rigorosos.
A principal abordagem são os testes matriciais: executar testes com todas as combinações de flags. Para CI/CD, isso pode ser muito caro (2^n combinações), então, na prática, todos os flags são testados individualmente em ambos os estados (ligado/desligado), e apenas combinações críticas são testadas. Testes unitários devem simular o valor do flag. Testes de integração verificam cenários específicos com valores de flags conhecidos. Testes E2E cobrem as combinações mais prováveis.
O processo de remoção: 1) certifique-se de que o flag esteja ativado em 100% para todos os usuários e não esteja sendo usado no modo de experimento; 2) remova todas as verificações condicionais do flag do código, mantendo apenas o branch “novo”; 3) remova a definição do flag do sistema de gerenciamento; 4) atualize os testes removendo os mocks para o flag removido. Recomenda-se automatizar esse processo via CI: flags inalterados por mais de N dias são marcados como obsoletos e exigem confirmação de remoção.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também