← Voltar a todos os artigos
Desafios

Monolito vs. Microsserviços: Qual Arquitetura Escolher para seu MVP

Por Marc Molas·22 de dezembro de 2023·10 min de leitura

Tem uma conversa que tenho pelo menos duas vezes por mês com fundadores que chegam pedindo ajuda com seu stack. Começa assim: "Queremos construir o MVP com microsserviços desde o início para não ter que reescrever depois."

É uma ideia que soa lógica. E na grande maioria dos casos, é um erro.

A obsessão com microsserviços vem de um lugar compreensível. Netflix, Spotify, Amazon — as empresas que mais admiramos em tecnologia evangelizam essa arquitetura há anos. Os artigos em blogs técnicos, as palestras em conferências e as threads no Twitter repetem a mesma mensagem: monolitos são legacy, microsserviços são o futuro.

O que esses artigos não contam é que a Netflix começou como monolito. O Spotify começou como monolito. A Amazon começou como monolito. Migraram para microsserviços quando tinham centenas de engenheiros, milhões de usuários e necessidades de escalabilidade que um monolito não conseguia atender. Não na fase de MVP.

Por que monolitos ganham para MVPs

Um monolito é uma aplicação deployada como uma unidade. Um repositório, um processo, um banco de dados. E para um MVP, é exatamente o que você precisa por razões muito concretas:

Velocidade de desenvolvimento. Em um monolito, um engenheiro pode implementar uma funcionalidade end-to-end sem coordenar com outros serviços, sem gerenciar comunicação entre processos e sem se preocupar com consistência de dados distribuídos. Chama uma função, não um endpoint HTTP. A diferença na velocidade de iteração é brutal.

Simplicidade de deploy. Um pipeline de CI/CD. Um servidor (ou um container). Um deploy. Não precisa de Kubernetes, service mesh, service discovery nem coordenação de versões entre serviços. Quando sua equipe é de 3-5 pessoas, essa simplicidade não é luxo — é sobrevivência.

Debugging direto. Quando algo falha em um monolito, você tem um stack trace. Uma rota clara do erro até a causa. Em microsserviços, uma falha pode se propagar por três serviços distintos, com logs distribuídos em diferentes sistemas, latências de rede que obscurecem a causa raiz e falhas em cascata que transformam um bug simples em uma investigação de horas.

Refactoring sem medo. Em um monolito, você pode mover código entre módulos, renomear funções e mudar interfaces internas sem quebrar contratos de API entre serviços. Sua IDE mostra todas as referências. Seus testes cobrem o fluxo completo. Em microsserviços, uma mudança no schema de um evento pode quebrar três serviços downstream sem que você perceba até chegar em produção.

Um único modelo de dados. Um banco de dados, um schema, uma fonte de verdade. Não precisa decidir qual serviço é o "dono" da entidade usuário, não precisa sincronizar dados entre serviços, não precisa de eventual consistency quando seu produto ainda está definindo que dados precisa armazenar.

Quando microsserviços fazem sentido

Microsserviços resolvem problemas reais. Mas são problemas que a maioria dos MVPs não tem:

Múltiplas equipes trabalhando em paralelo. Se você tem 30 engenheiros divididos em 6 equipes, um monolito vira gargalo. Conflitos de merge são constantes, deploys exigem coordenação entre equipes e um erro de uma equipe pode bloquear o release de todas. Microsserviços permitem que cada equipe faça deploy de forma independente.

Necessidades de escalabilidade diferenciadas. Seu serviço de processamento de imagens precisa de GPUs e escala com o volume de uploads. Sua API de busca precisa de muita RAM e escala com o número de queries. Seu serviço de notificações é intensivo em I/O e escala com usuários ativos. Se cada componente tem padrões de escalabilidade radicalmente diferentes, deployá-los separadamente permite otimizar recursos.

Requisitos tecnológicos distintos por serviço. Seu motor de recomendação funciona melhor em Python com ML libraries. Sua API de tempo real precisa de WebSockets em Node.js. Seu sistema de faturamento exige as garantias transacionais do Java. Microsserviços permitem escolher a tecnologia ideal para cada domínio.

Seu MVP tem 30 engenheiros? Precisa escalar componentes de forma independente? Requer três linguagens de programação diferentes? Provavelmente não. Então não precisa de microsserviços.

O sweet spot: o monolito modular

A melhor decisão para a maioria das startups não é o monolito clássico (tudo acoplado) nem microsserviços (tudo separado). É o monolito modular.

Um monolito modular é deployado como uma unidade, mas internamente está organizado em módulos com limites claros. Cada módulo tem sua própria lógica de negócio, seus próprios modelos de dados e uma interface pública bem definida. Os módulos se comunicam por interfaces internas — não chamadas HTTP, mas contratos de código.

Você mantém toda a simplicidade do monolito (um deploy, um banco de dados, debugging direto), mas com a modularidade que precisa para escalar. Quando chegar a hora de extrair um módulo como serviço independente, os limites já estão definidos.

A chave é disciplina. Não chame diretamente as funções internas de outro módulo. Não compartilhe modelos de dados entre módulos. Use a interface pública. A tentação de pegar atalhos é constante quando tudo está no mesmo repositório — e aqui é onde um engenheiro senior com experiência em arquitetura faz a diferença.

Os custos reais de microsserviços prematuros

Se ainda está tentado por microsserviços para seu MVP, considere os custos que raramente aparecem nos artigos que os promovem:

Complexidade de DevOps. Cada serviço precisa do seu próprio pipeline de CI/CD, sua própria configuração de deploy, seu próprio monitoramento. Com 5 microsserviços, você tem 5 pipelines para manter. Com um monolito, tem um.

Overhead de infraestrutura. Kubernetes, service mesh, logging centralizado, tracing distribuído, health checks por serviço. Nada disso é de graça — nem em dinheiro nem em tempo de engenharia.

Latência de rede. O que antes era uma chamada de função em memória (nanossegundos) agora é uma chamada HTTP ou gRPC (milissegundos). Multiplique isso por cada interação entre serviços em um request do usuário.

Consistência de dados. Com um banco de dados por serviço, você perde transações ACID entre serviços. Precisa de sagas ou eventual consistency. Para um MVP que ainda está definindo seu modelo de dados, isso é complexidade prematura.

Debugging distribuído. Um bug que em um monolito se diagnostica em 15 minutos pode levar meio dia em microsserviços. O erro se originou no serviço A, propagou para o B e o usuário viu no C. Sem tracing distribuído bem configurado, você está navegando às cegas.

Um framework de decisão simples

Antes de escolher arquitetura, responda estas perguntas:

  • Sua equipe tem menos de 8 engenheiros? → Monolito.
  • Está construindo um único produto? → Monolito.
  • Está em fase pre-seed, seed ou Série A inicial? → Monolito.
  • Sua prioridade é velocidade de iteração e time-to-market? → Monolito.
  • Pode arcar com o custo de uma equipe de DevOps dedicada? → Se não, monolito.

Se respondeu "monolito" a tudo: construa um monolito modular com limites claros entre módulos. Quando tiver 20+ engenheiros, múltiplas equipes e necessidades de escalabilidade diferenciadas, estará em posição de extrair serviços de forma incremental — sem reescrever do zero.

Como projetar um monolito fácil de decompor depois

Se aceita que o monolito é a decisão certa hoje, a próxima pergunta é como evitar que se torne uma bola de lama impossível de decompor quando chegar a hora. Estas são as práticas que funcionam:

  • Organize o código por domínio de negócio, não por camada técnica. Em vez de pastas /controllers, /models, /services, use /billing, /users, /notifications. Cada domínio contém seus próprios controllers, models e services.
  • Defina interfaces explícitas entre módulos. Cada módulo expõe uma API interna (funções, classes, interfaces) e oculta sua implementação. Nenhum módulo acessa diretamente o banco de dados de outro.
  • Um banco de dados, mas schemas separados. Use schemas ou prefixos de tabela para separar os dados de cada módulo. Isso facilita a extração futura.
  • Evite dependências circulares. Se o módulo A depende de B e B depende de A, você tem um problema de design que será muito pior quando tentar separá-los.
  • Testes por módulo. Cada módulo tem seus próprios testes unitários e de integração. Se consegue testar um módulo isoladamente, consegue extraí-lo isoladamente.

Essas práticas não exigem mais tempo de desenvolvimento. Exigem mais disciplina de design. E essa disciplina é o que diferencia um engenheiro senior de um junior — não o framework que usa, mas como estrutura o código para que a equipe que vier depois consiga trabalhar com ele.

Na Conectia, os engenheiros seniores que fornecemos a startups europeias construíram e decompuseram monolitos em empresas de todos os tamanhos. Não chegam com opinião dogmática sobre monolitos vs. microsserviços — chegam com experiência para avaliar seu caso concreto e tomar a decisão certa. Porque a arquitetura certa não é a que está na moda. É a que permite entregar valor ao usuário o mais rápido possível com a equipe que você tem hoje.


Não tem certeza de qual arquitetura seu produto precisa? Fale com um CTO — avaliamos seu caso e recomendamos a arquitetura que se encaixa no seu estágio e na sua equipe.

Pronto para construir a sua equipa de engenharia?

Fale com um parceiro técnico e implemente desenvolvedores validados por CTOs em 72 horas.