
Você já passou por isso: uma nova funcionalidade pronta, mas o time inteiro suando para fazer o deploy. “E se der errado?” “Precisamos esperar a madrugada.” “Vamos rezar para não precisar reverter.” O medo de implantar é um dos maiores freios à inovação em software.
A solução não é testar mais (embora testes ajudem). A solução é feature flags – também conhecidas como toggles de funcionalidade. Com elas, você pode liberar uma mudança para 1% dos usuários, testar em produção, e reverter em segundos se algo der errado. Tudo sem novo deploy.
Neste post, vamos mostrar como implementar feature flags em Go, desde uma solução simples até integração com ferramentas maduras, e como a Jacobus Software usa essa técnica para fazer deploys sem sustos – mesmo às 15h de uma sexta-feira.
O que são feature flags?
Feature flags são condicionais no código que controlam se uma funcionalidade está ativa ou não, sem precisar alterar o código novamente. A decisão pode ser baseada em:
- Percentual de usuários (10%, 50%, 100%)
- Lista branca (apenas usuários internos ou beta)
- Regras de negócio (apenas na região Sul, apenas para clientes premium)
- Data/hora (ativar automaticamente em 01/06/2026)
if featureFlags.IsEnabled("novo_checkout") {
// novo fluxo de checkout
} else {
// fluxo antigo
}
Com um simples toggle, você pode:
- Testar em produção – liberar para um grupo pequeno e validar métricas
- Fazer canary deploy – aumentar gradualmente até 100%
- Reverter instantaneamente – desligar a flag sem rollback de código
- Desacoplar deploy de lançamento – código no ar, funcionalidade desligada até a data de marketing
Implementação simples: feature flags com map em memória
Para começar, uma implementação minimalista (não recomendada para produção, mas ótima para entender o conceito):
type FeatureFlag struct {
Name string
Enabled bool
}
var flags = map[string]bool{
"novo_checkout": false,
"relatorio_novo": true,
}
func IsEnabled(name string) bool {
return flags[name]
}
Problemas: precisa recompilar para mudar, não funciona em múltiplos servidores.
Implementação para produção: flags no Redis com Go
Uma solução prática: armazenar flags no Redis e cachear em memória para performance.
import (
"context"
"sync"
"time"
"github.com/redis/go-redis/v9"
)
type FlagService struct {
rdb *redis.Client
mu sync.RWMutex
cache map[string]bool
ttl time.Duration
}
func NewFlagService(rdb *redis.Client) *FlagService {
s := &FlagService{
rdb: rdb,
cache: make(map[string]bool),
ttl: 10 * time.Second,
}
go s.refreshCache()
return s
}
func (s *FlagService) IsEnabled(ctx context.Context, flagName string) bool {
s.mu.RLock()
val, ok := s.cache[flagName]
s.mu.RUnlock()
if ok {
return val
}
// fallback para Redis
enabled, err := s.rdb.Get(ctx, "flag:"+flagName).Bool()
if err == nil {
s.mu.Lock()
s.cache[flagName] = enabled
s.mu.Unlock()
return enabled
}
return false // default
}
func (s *FlagService) refreshCache() {
ticker := time.NewTicker(s.ttl)
for range ticker.C {
// recarrega todas as flags
}
}
Vantagens: atualização em tempo real (TTL pequeno), compartilhado entre múltiplas instâncias, fácil integração com painel de admin.
Feature flags por percentual de usuários
Nem toda flag é liga/desliga. Muitas vezes você quer liberar gradualmente, por exemplo, 10% dos usuários.
func (s *FlagService) IsEnabledForUser(flagName string, userID string) bool {
// Primeiro, flag global está ativa?
if !s.IsGlobalEnabled(flagName) {
return false
}
// Percentual configurado (ex: "novo_checkout:20" = 20% dos usuários)
percentage := s.GetPercentage(flagName) // 0-100
// Hashing consistente para o mesmo usuário sempre cair no mesmo grupo
hash := fnv.New32a()
hash.Write([]byte(flagName + userID))
bucket := hash.Sum32() % 100
return bucket < uint32(percentage)
}
Assim, o mesmo usuário vê a mesma experiência sempre, mesmo entre requisições.
Feature flags com SDKs profissionais
Para necessidades mais complexas (paineis web, segmentação avançada, auditoria), use soluções prontas:
| Ferramenta | Go SDK | Ideal para |
|---|---|---|
| LaunchDarkly | Sim, maduro | Empresas com time de produto dedicado |
| Flagsmith | Sim, open-source | Times que querem self-hosted |
| Unleash | Sim | Open-source, boa UI |
| go-feature-flag | Nativo | Solução 100% Go, simples |
Exemplo com LaunchDarkly em Go:
import ld "github.com/launchdarkly/go-server-sdk"
ldClient, _ := ld.MakeClient("sdk-key", 5*time.Second)
enabled, _ := ldClient.BoolVariation("novo-checkout", ldUser, false)
Feature flags + CI/CD: o fluxo completo
Na Jacobus, integramos feature flags ao pipeline de entrega contínua:
- Desenvolvedor implementa nova funcionalidade protegida por flag
"feature_x"(default desligada). - Pull request → merge na main → deploy automático (flag continua desligada).
- QA ativa flag via painel para ambiente de staging/homologação.
- Testes aprovados → deploy em produção com flag ainda desligada.
- Ativação gradual: 1% → 10% → 50% → 100%, monitorando métricas de erro e latência.
- Se erro sobe, desliga flag (rollback em segundos, sem novo deploy).
- Após 100% estável por uma semana, removemos o código antigo e a flag (cleanup).
Esse fluxo elimina o medo de deploy. Lançamentos deixam de ser eventos de risco e viram rotina.
Cuidados e boas práticas
⚠️ Não use feature flags para tudo
- Flags aumentam complexidade (caminhos condicionais no código).
- Remova flags antigas assim que a funcionalidade estiver estável (evite “lixo de flags”).
- Teste o código com flag ligada e desligada.
⚠️ Atenção a flags em contexto de banco de dados
Se a flag controla um novo schema de banco, você precisa lidar com migrações compatíveis com os dois fluxos.
⚠️ Performance de verificação de flags
Evite consultar flags a cada requisição via rede (Redis, LaunchDarkly) sem cache local. Use TTLs curtos (ex: 10s) e cache em memória.
Exemplo real: checkout dois-passos na Jacobus
Um cliente e-commerce queria migrar o checkout de uma página para duas páginas, mas com medo de impacto na conversão. Implementamos:
- Flag
"checkout_dois_passos"com percentual ajustável. - Começamos com 1% dos usuários.
- Métricas de abandono de carrinho comparadas entre grupos.
- Com dados positivos, subimos para 10%, 50%, 100% em 2 semanas.
- Zero incidentes. Conversão final aumentou 8%.
Sem feature flags, seria um deploy monolítico com risco alto – ou meses de protótipo fora de produção.
Conclusão: feature flags são ferramentas de coragem
Deploy não precisa ser um momento de tensão. Com feature flags em Go, você ganha a capacidade de testar hipóteses em produção, reduzir risco e acelerar a entrega de valor.
Na Jacobus Software, feature flags são padrão em todos os nossos projetos. Porque acreditamos que inovação não pode esperar pela madrugada.
🚦 Quer deploy sem medo no seu sistema Go?
Nossos especialistas implementam feature flags com cache distribuído (Redis) ou SDKs profissionais, e integram ao seu CI/CD para que você lance novas funcionalidades a qualquer momento, com segurança.
