Monolito ou microsserviços? A pergunta certa é outra
Microsserviços resolvem um problema organizacional, não técnico. Como decidir a granularidade da arquitetura sem pagar complexidade distribuída à toa.
A escolha entre monolito e microsserviços virou identidade de time, e isso atrapalha a decisão. Vale trocar o enquadramento: as duas coisas são pontos num eixo de granularidade, e a pergunta útil não é "qual dos dois", é onde cortar e por quê.
O que microsserviços realmente resolvem
A justificativa técnica mais repetida — "escala" — é a mais fraca. Um monolito bem construído roda atrás de um balanceador com dez réplicas sem cerimônia. Escala horizontal não exige separar serviços; exige não guardar estado na memória do processo.
O que microsserviços resolvem de verdade é acoplamento entre equipes:
- Times diferentes precisam liberar em ritmos diferentes.
- Um time não pode ser bloqueado pela suíte de testes de outro.
- Partes do sistema têm requisitos de disponibilidade incompatíveis.
- Uma parte precisa de uma stack que o resto não usa (processamento de vídeo, machine learning).
Repare que quase tudo aí é organizacional. A Lei de Conway não é uma curiosidade: a arquitetura tende a espelhar a estrutura de comunicação de quem constrói. Microsserviços são uma resposta a um problema de pessoas, com custo pago em tecnologia.
Se você tem um time de seis pessoas, você não tem esse problema. Tem outros, e microsserviços vão piorá-los.
O preço que ninguém coloca na planilha
Ao cortar um processo em serviços de rede, uma chamada de função vira uma chamada remota. Isso muda categoria de coisa:
A chamada passa a falhar de formas novas. Timeout, resposta parcial, serviço fora do ar, rede lenta. Cada ponto de integração precisa de timeout, retry com backoff, idempotência e circuit breaker. Isso é código que não existe no monolito.
A transação some. No monolito, gravar pedido e baixar estoque é um BEGIN/COMMIT. Distribuído, você precisa de saga com compensação — e agora precisa responder "o que fazer quando a baixa de estoque falha depois do pagamento aprovado". Essa pergunta não tem resposta fácil, e ela é de negócio, não de infraestrutura.
Debugar exige ferramenta. Reproduzir um bug que atravessa quatro serviços sem tracing distribuído é arqueologia. Você precisa de correlação de requisição, log estruturado agregado e um lugar para ver tudo junto. Isso é plataforma, e alguém precisa mantê-la.
A consistência vira eventual. Um dado gravado num serviço leva tempo até refletir no outro. Isso aparece na tela do usuário e vira ticket de suporte: "cadastrei e não apareceu". Não é bug, é a arquitetura escolhida — mas alguém precisa ter decidido isso conscientemente.
Nada disso é impeditivo. É custo. E é um custo fixo que você paga todo mês, com ou sem benefício.
Um caminho mais sensato: monolito modular
Para a maioria das empresas, o ponto ótimo fica no meio: um deploy, fronteiras internas explícitas.
Na prática:
- O código é organizado por domínio de negócio (
pedidos,estoque,faturamento), não por camada técnica (controllers,services,repositories). - Cada módulo expõe uma interface pública pequena; o resto é interno e o compilador ou o linter garante isso.
- Módulos não acessam a tabela um do outro. Nem "só para essa consulta". É aqui que a disciplina morre primeiro.
- Cada módulo tem seu próprio esquema no banco, mesmo compartilhando a instância.
Com isso você fica com a maior parte do benefício — fronteiras claras, times que não se atropelam, raciocínio local — sem pagar rede, sem sagas, sem plataforma de observabilidade distribuída.
E tem um bônus decisivo: quando um módulo realmente precisar virar serviço, o corte já está feito. A fronteira existe, o contrato existe, só muda o transporte. Extrair um módulo bem isolado é trabalho de semanas. Extrair de uma bola de lama é trabalho de trimestres.
Quando separar de fato
Vale extrair um serviço quando pelo menos um destes é concretamente verdadeiro:
- O perfil de recurso é incompatível. Processamento de vídeo que precisa de GPU não deve compartilhar processo com a API que responde em 50 ms.
- O requisito de disponibilidade é diferente. O checkout precisa de 99,99%; o gerador de relatório mensal não. Separar impede que um derrube o outro.
- A cadência de mudança é radicalmente diferente. Um módulo muda três vezes por dia, outro duas vezes por ano.
- A fronteira organizacional é real. Times distintos, com autonomia de roadmap e responsabilidade de plantão sobre aquilo.
Um critério prático que usamos: se você não consegue nomear o serviço sem usar a palavra "service" ou "manager", provavelmente a fronteira não está clara o suficiente para virar rede.
Como decidir no seu caso
Três perguntas, na ordem:
- Quantas pessoas mexem no código hoje, e quantas vão mexer em dois anos? Abaixo de dez, monolito modular quase sempre vence.
- Qual entrega está bloqueada por causa da arquitetura atual? Se você não consegue nomear uma, o problema provavelmente é processo, não estrutura.
- Sua equipe tem observabilidade distribuída rodando hoje? Se não tem, adotar microsserviços significa construir isso antes — e esse projeto costuma ser maior que o problema original.
Arquitetura é a soma das decisões difíceis de reverter. Vale registrar cada uma por escrito, com contexto e consequências, para que ninguém precise refazer a discussão a cada seis meses. É parte do que entregamos em consultoria de arquitetura.
Se você está no meio dessa decisão, descreva seu contexto — é o tipo de conversa que resolvemos em uma hora.