A figueira que dá nome ao padrão
A figueira estranguladora começa como uma muda no alto de uma árvore hospedeira e vai descendo raízes por fora do tronco dela. Aos poucos, essas raízes envolvem a árvore inteira, assumindo o trabalho de sustentar a copa. Quando a hospedeira finalmente morre e apodrece, a figueira já está de pé sozinha, no formato exato da árvore que substituiu — sem que a floresta jamais visse um buraco onde havia uma árvore. A migração Strangler Fig faz isso com software: o novo cresce em volta do velho até poder ficar de pé sem ele.
Por que não o big-bang
A reescrita total falha por uma razão estrutural: ela concentra todo o risco num único evento futuro. Durante meses não há entrega, o novo persegue um legado que continua mudando, e requisitos escondidos no velho só aparecem quando já é tarde. O dia da virada é tudo-ou-nada.
O Strangler Fig troca esse evento único por uma sequência de migrações pequenas, cada uma em produção e reversível. Se uma rota migrada dá problema, você a aponta de volta para o legado — o raio de dano é uma funcionalidade, não o sistema inteiro.
A peça técnica que viabiliza tudo é a fachada de roteamento na frente dos dois sistemas: ela recebe todas as requisições e decide, por rota, quem atende. No começo, tudo vai ao legado; a cada release, mais rotas apontam para o novo; no fim, nada sobra no velho e ele é desligado. Um API Gateway costuma ser exatamente esse roteador, o que faz o padrão se encaixar naturalmente em quem já tem um.
O ponto mais espinhoso não é o código, são os dados. Enquanto rotas do legado e do novo coexistem, ambos leem e escrevem dados relacionados, e é preciso mantê-los consistentes: por um banco compartilhado temporário, por sincronização, ou por dupla escrita durante a transição. É aqui que entra a camada anticorrupção — a fronteira que traduz o modelo do legado para o do sistema novo, para que o novo não nasça já contaminado pelo modelo que está substituindo. Sem cuidar dos dados, o Strangler Fig vira dois sistemas discordando sobre a verdade; com esse cuidado, ele é a forma mais segura conhecida de aposentar um legado.
Como isso aparece na prática
O monólito legado aposentado sem parar
Cenário
Uma empresa precisava substituir um monólito de quinze anos, mas o negócio não podia parar e uma reescrita big-bang anterior já havia sido cancelada depois de um ano sem entregar nada.
Como o padrão entra
Um roteador foi posto na frente do monólito, e as funcionalidades foram reescritas uma a uma no sistema novo, migrando rota a rota. A cada release, o legado atendia menos; ao fim, foi desligado.
Trade-off: A migração durou bem mais que um big-bang teórico, e exigiu manter e sincronizar os dois sistemas o tempo todo. Em troca, o negócio nunca parou, e cada passo era reversível se desse errado.
A rota migrada que voltou para o legado
Cenário
Durante a migração, uma funcionalidade reescrita apresentou um bug sutil de cálculo que só apareceu com tráfego real, ameaçando dados de clientes.
Como o padrão entra
Como o roteador controlava o destino por rota, aquela funcionalidade foi reapontada para o legado em minutos, enquanto o bug era corrigido no novo, sem afetar o resto da migração.
Trade-off: Aquela rota ficou temporariamente no sistema antigo, atrasando um pouco o cronograma. É exatamente o valor do padrão: o problema ficou contido numa funcionalidade e foi revertido, em vez de derrubar uma virada inteira.
Onde isto dá errado
Ignorar a sincronização de dados
Enquanto legado e novo coexistem, os dois tocam os mesmos dados. Sem sincronização, banco compartilhado temporário ou dupla escrita, os dois sistemas passam a discordar sobre a verdade — o ponto mais espinhoso da migração, e o mais esquecido.
Deixar a migração parar no meio
Conviver com dois sistemas é caro e deveria ser temporário. Sem dono e prazo, a migração estaciona e o roteador vira permanente, com metade no velho e metade no novo — o custo da transição sem o benefício da conclusão.
Deixar o modelo do legado contaminar o novo
Se o sistema novo lê o legado sem uma camada anticorrupção, o modelo torto do velho vaza para o novo, que nasce já com os vícios que deveria eliminar. A tradução na fronteira é o que preserva o modelo limpo.
Rotear por rota, migrar aos poucos
// A reescrita big-bang: parar tudo, reescrever por meses, virar a chave
// num dia. Historicamente, a forma mais confiavel de matar um sistema.
// STRANGLER FIG: um roteador na frente decide, rota a rota, o que ja
// foi migrado (vai ao novo) e o que ainda nao (vai ao legado).
function rotear(req: Request) {
const migradas = ["/pedidos", "/carrinho"]; // ja reescritas no novo
if (migradas.some((p) => req.path.startsWith(p))) {
return encaminhar(req, "http://sistema-novo"); // <- novo
}
return encaminhar(req, "http://sistema-legado"); // <- velho, ainda
}
// A cada release, mais uma rota migra: a lista "migradas" cresce,
// o legado encolhe. O usuario nunca ve um big-bang — ve o sistema
// funcionando o tempo todo, enquanto por dentro ele e substituido.
// Quando a ultima rota migrar, o legado e desligado. Sem virada de chave.Quando usar × quando evitar
Use quando
3- Ao substituir um legado grande demais para um big-bang seguro.
- Quando o sistema precisa funcionar e evoluir durante a migração.
- Quando reduzir risco em passos reversíveis vale mais que a velocidade.
Evite quando
2- Em sistemas pequenos, onde a reescrita direta é de baixo risco.
- Quando manter e sincronizar os dois lados custaria mais que um corte limpo.
Testar o que ficou
3 armadilhas de Strangler Fig viram perguntas, com o nome do padrão escondido, misturadas com padrões parecidos.
Onde isto aparece de verdade
Você já usa isto, talvez sem saber o nome.
o proxy que roteia velho × novoUm roteador na frente decide, rota a rota, o que já foi migrado (vai ao novo) e o que ainda não (vai ao legado).migração por rota, não big-bangSubstituir o sistema antigo pedaço a pedaço, com o novo crescendo em volta dele, até o velho poder ser desligado.o legado que encolhe até sumirO sistema antigo vai perdendo funções para o novo até restar nada — a figueira que estrangulou a árvore hospedeira.
O padrão em uma linha
Sem nome de domínio, sem cerimônia. Só a ideia.
// Novo cresce ao redor; legado encolhe.
proxy.rota("/checkout", podeNovo ? novo : legado);O que ele cobra
1 salto a mais entre a chamada e o efeito.
- Manter os dois sistemas vivos e o roteador de fronteira durante toda a migração, que pode durar bastante
- Dados que os dois lados leem e escrevem exigem sincronização ou dupla escrita enquanto durar a transição
Não vale se: o sistema é pequeno e a reescrita direta é rápida e de baixo risco — aí conviver com o legado custa mais do que um corte limpo.
Onde isto aparece
Continue por aqui
- Anti-corruption layerTodo sistema novo acaba tendo que conversar com um velho — um ERP legado, uma API de terceiro, um modelo que não se controla. A camada anticorrupção é a fronteira que traduz o modelo do outro para o seu e impede que o vocabulário torto dele entre no seu domínio. É o Adapter elevado à escala de um modelo inteiro: a sujeira fica confinada na borda, e o domínio novo nunca a vê.
- Monólito modularO meio-termo que a moda dos microsserviços fez esquecer: um único deploy, mas com módulos de fronteiras internas reais, cada um escondendo suas entranhas atrás de uma API pública. Dá a maior parte do benefício da modularização — responsabilidades separadas, mudanças isoladas — sem pagar a rede, a consistência eventual e o custo operacional de distribuir. Costuma ser o ponto de partida certo, e o destino final de muita gente.
- MicrosserviçosDividir o sistema em serviços pequenos e autônomos, cada um com seu deploy, seu banco e sua escala. Compra autonomia — times e serviços evoluem independentes — e cobra caro: a rede entra no meio de tudo, transações viram sagas, e cada serviço vira um sistema a operar. É uma troca de complexidade de código por complexidade operacional, e só vale quando a autonomia resolve um problema que você de fato tem.