Reescrever do zero é a fantasia mais cara da engenharia de software. 62% dos projetos de reescrita completa são cancelados ou ultrapassam o orçamento em mais de 200%. A alternativa que funciona: decompor o monolito gradualmente, módulo por módulo, com o sistema em produção o tempo inteiro. Sem big bang. Sem downtime. Sem apostas.
Monolitos não são ruins por definição — são ruins quando crescem além da capacidade da equipe de mantê-los. Nesse ponto, cada mudança simples se torna uma operação de alto risco.
No monolito, cada deploy é all-or-nothing. Uma alteração no módulo de relatórios obriga a redesploy do checkout, do financeiro e do cadastro. Um bug em qualquer ponto derruba tudo. Equipes evitam deploys por medo — e a velocidade de entrega despenca para 1-2 releases por mês.
O módulo de processamento de pagamentos precisa de 10x mais recursos na Black Friday. Mas como é um monolito, você escala tudo — inclusive os módulos que não precisam. Resultado: custo de infraestrutura 5x maior do que o necessário nos picos, e subutilização no resto do ano.
Quando 5 equipes trabalham no mesmo repositório com acoplamento forte, cada merge é um conflito potencial. O time de checkout espera o time de cadastro terminar. Ninguém pode mover rápido porque todos dependem de todos. A coordenação consome mais energia que o desenvolvimento.
O monolito foi construído em Java 8, ou PHP 5, ou .NET Framework. Adotar uma tecnologia mais adequada para um módulo específico é impossível — tudo precisa rodar no mesmo runtime. A equipe fica presa em frameworks desatualizados porque o custo de migrar o monolito inteiro é proibitivo.
Como a figueira-estranguladora que envolve a árvore hospedeira até assumir completamente, construímos o novo sistema ao redor do legado. O monolito continua em produção enquanto cada módulo é extraído e substituído. Sem interrupção, sem pressa, sem risco desnecessário.
Analisamos o monolito para identificar fronteiras naturais de domínio: onde os dados e as regras de negócio se agrupam de forma coesa. Mapeamos dependências entre módulos, volume de comunicação e acoplamento real. O resultado é um mapa de bounded contexts que define a ordem de extração.
Criamos uma camada de fachada (API Gateway ou proxy reverso) na frente do monolito. Inicialmente, 100% do tráfego vai para o legado. Conforme cada módulo novo fica pronto, o tráfego migra gradualmente: 5%, 20%, 50%, 100%. O monolito nem percebe que está sendo substituído.
Cada bounded context é extraído para um serviço independente com seu próprio banco de dados, sua própria pipeline de deploy e seus próprios testes. Começamos pelo módulo de menor risco e maior valor para criar momentum e aprendizado. Cada extração bem-sucedida reduz o escopo do monolito.
Substituímos chamadas diretas ao banco compartilhado por APIs e eventos assíncronos. Cada serviço passa a ser dono dos seus dados — sem tabela compartilhada, sem acoplamento de schema. Isso viabiliza deploys independentes e permite que cada equipe evolua seu módulo no seu próprio ritmo.
Cada equipe deploya seu serviço quando quiser, sem coordenação com outras equipes. O time de checkout deploya 3x por dia se precisar, sem tocar no financeiro. Frequência de deploy típica sobe de 2x/mês para 10x/semana — com menos risco em cada release.
Escale apenas o módulo que precisa. O processamento de pagamentos ganha mais réplicas na Black Friday enquanto o cadastro continua com uma instância. Clientes reportam redução média de 40% no custo de infraestrutura após a decomposição completa.
Com bounded contexts claros e deploys independentes, equipes param de pisar umas nas outras. O tempo de ciclo (da ideia ao deploy) cai drasticamente. Features que demoravam meses no monolito são entregues em semanas nos serviços independentes.
Decomposição gradual com Strangler Fig Pattern. Sem reescrita, sem big bang, sem downtime. O legado continua rodando enquanto modernizamos módulo por módulo.