Modernizar um legado sem parar a operação: o padrão que usamos
Sistema legado não é sinônimo de sistema ruim. Na maior parte das vezes, é o sistema que sustenta a receita da empresa há anos, feito por pessoas que já saíram, em uma tecnologia que ninguém quer mais manter. Ele funciona. O problema é que cada mudança custa mais que a anterior, e a fila de pedidos do negócio só cresce.
Quando essa dor chega ao limite, a proposta que costuma aparecer é reescrever tudo. Novo stack, nova arquitetura, novo time, data de virada marcada. Parece limpo. Quase nunca termina bem.
Nós trabalhamos com sistemas críticos desde 2009, e a lição mais consistente é simples: a modernização que dá certo é a que nunca para a operação. Este é o padrão que seguimos.
Por que a reescrita big-bang falha
A reescrita completa parte de três premissas que raramente se confirmam.
A primeira é que alguém sabe tudo o que o sistema faz. Não sabe. Sistemas com muitos anos de produção acumulam regras que ninguém documentou, exceções criadas para um cliente específico, comportamentos que só existem porque alguém corrigiu um bug há dez anos. A reescrita descobre essas regras do pior jeito: em produção, depois da virada.
A segunda é que o legado vai ficar parado enquanto o novo é construído. Não fica. O negócio continua pedindo mudanças, e elas precisam ser feitas nos dois sistemas ao mesmo tempo. O novo corre atrás de um alvo que se move.
A terceira é que a data de virada é uma data. Na prática é um período de meses em que os dois sistemas convivem mal, com dados divergentes e o time exausto. Muitos projetos são cancelados nesse ponto.
Modernização incremental: o padrão strangler fig
O nome vem de uma figueira que cresce ao redor da árvore hospedeira até substituí-la. Aplicado a software, a ideia é envolver o legado com uma camada nova e ir movendo capacidades para essa camada, uma a uma, até que o sistema antigo possa ser desligado sem ninguém notar.
O que muda em relação à reescrita é o risco. Cada passo é pequeno, reversível e observável em produção. Se algo quebra, o problema está em uma fatia, não no sistema inteiro.
Na prática, isso exige um ponto de entrada controlado, um gateway ou proxy que decide se cada requisição vai para o legado ou para o componente novo. Esse ponto é o coração da estratégia.
O primeiro passo não é código novo
Antes de escrever a primeira linha do sistema novo, precisamos de duas coisas: saber o que o legado faz e saber como ele se comporta em produção.
Observabilidade
Muitos legados rodam há anos sem métricas, com logs que ninguém lê. O primeiro investimento é instrumentar: quais rotas são usadas, com que frequência, com que latência, com que taxa de erro.
Testes de caracterização
Sistemas legados raramente têm testes automatizados. Testes de caracterização não verificam se o comportamento é correto, apenas registram qual é o comportamento atual: dada esta entrada, o sistema responde isto. Eles viram a rede de segurança da migração. Quando uma capacidade é movida para o componente novo, ela precisa passar nos mesmos testes. Se o comportamento antigo tinha um bug, decidimos conscientemente se mantemos ou corrigimos, nunca por acidente.
Fatiamento por capacidade de negócio
A pergunta seguinte é por onde começar. Não pela camada técnica (banco, depois API, depois interface), porque isso mantém o risco alto e não entrega nada visível. A resposta é fatiar por capacidade de negócio: emissão de notas, cálculo de comissão, cadastro de clientes, autenticação. Cada fatia faz sentido para quem usa o sistema, tem fronteiras identificáveis e pode ser movida inteira.
Para escolher a primeira, cruzamos três critérios: valor para o negócio, frequência de mudança e facilidade de isolamento. Não comece pelo módulo mais crítico e mais emaranhado. Comece por um que ensine o time e prove o método.
Feature flags e rollback como rotina
Cada fatia movida entra em produção atrás de uma feature flag. Isso permite ligar o componente novo para um percentual do tráfego, para um grupo de usuários ou para uma unidade de negócio específica, e comparar o comportamento com o legado em tempo real.
Quando o componente novo e o legado recebem a mesma entrada e o resultado é comparado sem afetar o usuário, chamamos de execução sombra. É a forma mais segura de validar a migração de uma regra complexa: o legado continua respondendo, o novo só registra a divergência.
E rollback precisa ser um clique, não um projeto. Se a flag desliga e o tráfego volta para o legado em segundos, o custo de errar é baixo e o time decide com mais coragem.
Transição de fornecedor sem perder conhecimento
Modernizar um legado quase sempre envolve mudar quem cuida dele. O conhecimento que está na cabeça das pessoas é o ativo mais frágil do projeto.
Nosso padrão é tratar a transição como uma fase com entregáveis próprios: mapa de dependências, inventário de integrações, rotinas agendadas, credenciais, incidentes recorrentes e como foram tratados. Tudo vai para um repositório do cliente, não do fornecedor.
E, durante um período, operamos junto com quem está saindo. Assumir a sustentação antes de começar a modernizar é a forma mais confiável de aprender como o sistema realmente se comporta.
Como saber que terminou
A modernização termina quando o legado pode ser desligado e ninguém percebe. Nenhuma rota recebe tráfego no sistema antigo, nenhuma rotina agendada depende dele, nenhuma integração externa aponta para ele, e o time consegue fazer uma mudança de ponta a ponta sem tocá-lo.
Na prática
Um roteiro resumido do padrão:
- Instrumente o legado antes de mexer nele. Descubra o que é usado e o que não é.
- Escreva testes de caracterização para as capacidades que serão movidas primeiro.
- Coloque um ponto de entrada controlado na frente do sistema.
- Fatie por capacidade de negócio, começando por uma que muda com frequência e é razoavelmente isolada.
- Mova cada fatia atrás de uma feature flag, com execução sombra quando houver regra complexa.
- Garanta rollback em segundos.
- Desligue partes do legado à medida que perdem tráfego.
É esse padrão que aplicamos em nosso serviço de sustentação e modernização: assumimos a operação do sistema atual e o modernizamos sem interromper o que já funciona.
Perguntas frequentes
Quanto tempo leva uma modernização incremental?
Depende do tamanho do sistema e de quantas capacidades precisam ser movidas. A diferença em relação à reescrita é o valor chegar desde as primeiras semanas e o risco ficar distribuído em vez de concentrado em uma virada. Definimos o ritmo a partir da primeira fatia.
Precisamos trocar de tecnologia para modernizar?
Não necessariamente. Em muitos casos, a maior parte do ganho vem de observabilidade, testes, separação de responsabilidades e automação de deploy, mantendo boa parte da tecnologia atual. A troca de stack é uma decisão por fatia, guiada por custo de manutenção e disponibilidade de pessoas, não uma premissa do projeto.
É possível modernizar enquanto o fornecedor atual ainda opera o sistema?
Sim, e é o cenário mais comum. Começamos assumindo a sustentação em paralelo, com um período de convivência para transferência de conhecimento. Isso reduz o risco de perder informação e permite que a modernização comece com o sistema já estável e observável.