10 min de leitura
saas
arquitectura
microserviços
postgres
devops

Microserviços com 10 utilizadores: quase sempre não vale a pena

Migrar para microserviços com 10 utilizadores raramente compensa. Vê quando faz sentido, custos escondidos, alternativas e sinais técnicos reais.

Líder técnico risca serviços num esquema perante três colegas sentados numa sala de reuniões luminosa

TL;DR

  • Com 10 utilizadores, microserviços são quase sempre uma distracção cara. O problema normal ainda é produto, vendas, onboarding e dados, não escalabilidade.
  • A alternativa correcta costuma ser um monólito modular com PostgreSQL 16, filas assíncronas e limites internos bem definidos.
  • Microserviços só começam a fazer sentido cedo se houver isolamento regulatório, cargas muito diferentes, equipas independentes ou integrações externas com risco operacional alto.
  • O custo real não é “ter mais repositórios”. É observabilidade, deploys, testes distribuídos, autenticação entre serviços, versionamento de APIs, incidentes e consistência de dados.
  • Antes de migrar, mede: p95 e p99, throughput, tempo de deploy, taxa de erro, duração de jobs, custo por ambiente e tempo gasto a diagnosticar incidentes.

A resposta curta: não, salvo raras excepções

Se tens 10 utilizadores, a resposta prática é: não vale a pena migrar para microserviços.

Não porque microserviços sejam maus. São uma ferramenta útil quando a complexidade organizacional e operacional já justifica a separação. O problema é usá-los antes de existirem os sintomas que eles resolvem.

Com 10 utilizadores, o risco mais provável não é a base de dados não escalar. É o produto ainda não ter encaixe no mercado, a equipa ainda não saber quais são os fluxos críticos, o domínio ainda estar a mudar todas as semanas e os requisitos ainda não terem estabilizado. Nestes cenários, distribuir o sistema por vários serviços só torna cada mudança mais lenta.

Na Impact Origin, quando olhamos para projectos em fases iniciais, incluindo clientes activos recentes com cerca de dois meses e billing ainda por definir, a pergunta raramente é “como separamos isto em serviços?”. A pergunta certa é mais dura: “que parte do sistema já provou que merece complexidade própria?”. Muitas vezes, nenhuma.

Também há projectos onde a stack ainda nem está formalizada de forma estável. Isso não é mau. É normal em fases iniciais. Mas se ainda estás a decidir tecnologia, modelo de dados, fluxos de pagamento, integração com ERP ou lógica de permissões, partir para microserviços é saltar três degraus.

A opinião forte: se ainda não consegues explicar claramente os limites do teu domínio numa folha A4, não devias estar a criar microserviços. Devias estar a clarificar o produto e a modularizar o monólito.

O custo real dos microserviços

Muita gente pensa em microserviços como “dividir a aplicação em partes pequenas”. Na prática, significa trocar chamadas locais por chamadas de rede, transacções simples por consistência eventual e bugs previsíveis por falhas parciais.

Uma chamada dentro do mesmo processo pode demorar microssegundos. Uma chamada HTTP interna, mesmo dentro da mesma região cloud, pode facilmente ficar entre 5 ms e 50 ms. Com TLS, autenticação, retries e serialização JSON, o p99 pode chegar a 100 ms ou mais em momentos de carga. Se uma página precisa de 5 serviços para responder, acabaste de criar uma cascata de latência.

O custo também aparece nestas áreas:

ÁreaMonólito modularMicroserviços
Deploy inicial1 pipeline3 a 10 pipelines
Debug localArrancar uma app e uma base de dadosOrquestrar vários serviços, filas, mocks e dependências
TestesIntegração directaContract testing, testes end-to-end frágeis, ambientes partilhados
DadosTransacções ACID simplesEventos, idempotência, reconciliação, consistência eventual
ObservabilidadeLogs e métricas por appTracing distribuído, correlação de logs, métricas por serviço
SegurançaSessão e permissões num pontoAutenticação serviço a serviço, scopes, rotação de segredos

Se usas Kubernetes, lê a própria documentação oficial antes de o meteres num produto pequeno: https://kubernetes.io/docs/home/. Kubernetes resolve problemas reais, mas cria uma superfície operacional grande. Namespaces, ingress, probes, autoscaling, secrets, network policies, RBAC e upgrades do cluster não são gratuitos em tempo.

Com 10 utilizadores, muitas equipas ficariam melhor com uma VM bem configurada, Docker Compose para ambientes simples, PostgreSQL gerido e uma pipeline CI/CD decente. Por exemplo: GitHub Actions, Render, Fly.io, Heroku, Railway ou AWS App Runner podem ser mais que suficientes, dependendo dos requisitos de compliance e rede.

O ponto não é “nunca uses cloud complexa”. O ponto é: não compres complexidade operacional antes de teres carga, receita ou risco que a pague.

O que deves construir em vez disso

A arquitectura que recomendo na maioria dos SaaS B2B pequenos é um monólito modular.

Isto não significa uma bola de lama. Significa uma aplicação única, com fronteiras internas claras. Por exemplo:

  • módulo de contas e organizações
  • módulo de billing
  • módulo de permissões
  • módulo de integrações
  • módulo de notificações
  • módulo de reporting
  • módulo de tarefas assíncronas

A base pode ser Node.js 22 LTS com Fastify ou NestJS, Ruby on Rails 8, Django 5, Laravel 11.NET 8 ou Phoenix 1.7. A tecnologia interessa menos do que a disciplina nas fronteiras.

Para dados, PostgreSQL 16 chega muito longe. Tens transacções, índices parciais, JSONB quando necessário, Row Level Security, materialized views e extensões úteis. A documentação oficial é excelente: https://www.postgresql.org/docs/16/.

Para jobs, podes começar com uma fila simples. BullMQ com Redis é comum em Node.js. pgmq é interessante quando queres reduzir infra e usar PostgreSQL como fila. Se o volume é baixo, por exemplo 1.000 a 50.000 jobs por dia, não precisas de Kafka. Kafka é óptimo quando tens streams sérios, múltiplos consumidores e retenção de eventos como requisito. Para enviar emails, gerar PDFs, sincronizar com um ERP ou processar webhooks, uma fila normal resolve.

Uma regra que funciona bem: mantém o deploy único, mas impede acoplamento interno descontrolado.

Podes fazer isto com convenções simples:

  • cada módulo tem a sua pasta, os seus serviços e os seus repositórios de dados
  • módulos não acedem directamente às tabelas uns dos outros sem passar por uma interface interna
  • eventos internos são explícitos, mesmo dentro do monólito
  • jobs são idempotentes desde o início
  • permissões são centralizadas, não espalhadas por controllers

Isto dá-te uma vantagem enorme: quando um módulo provar que merece existir como serviço separado, já tens uma fronteira conceptual. A extracção passa a ser uma decisão técnica, não uma cirurgia de emergência.

Quando microserviços podem fazer sentido mesmo cedo

Há excepções. Poucas, mas reais.

A primeira é isolamento regulatório ou de dados. Se tens um componente que trata dados clínicos sensíveis, dados financeiros críticos ou informação com requisitos legais diferentes, pode fazer sentido isolá-lo. Em healthtech e fintech, esta conversa aparece cedo. Não por performance, mas por risco, auditoria e acesso mínimo necessário.

A segunda é carga muito assimétrica. Imagina uma aplicação com 10 utilizadores humanos, mas que recepciona 2 milhões de webhooks por mês de uma plataforma externa. A contagem de utilizadores engana. O sistema que processa eventos pode precisar de escala, retries, dead letter queues e limitação de taxa muito antes da interface administrativa precisar.

A terceira é ciclo de vida diferente. Se tens um motor de cálculo, processamento de imagem, ingestão de ficheiros grandes ou sincronização com ERP que muda e escala de forma independente, talvez faça sentido separá-lo. Mesmo assim, muitas vezes começa como worker separado no mesmo repositório, não como ecossistema de microserviços.

A quarta é equipa. Microserviços têm mais a ver com equipas do que com computadores. Se tens uma equipa de 20 engenheiros distribuída por domínios diferentes, a separação pode reduzir conflitos. Se tens 2 ou 3 pessoas, normalmente aumenta a coordenação.

A quinta é dependência externa perigosa. Integrações com ERPs, CRMs, gateways de pagamento e plataformas eCommerce podem falhar de formas desagradáveis. Nesses casos, isolar um conector pode ser útil. Ainda assim, isolamento não exige sempre microserviço. Pode ser uma queue, uma tabela de outbox e um worker bem desenhado.

A armadilha comum: partir a base de dados cedo demais

A pior migração para microserviços é aquela que começa pela base de dados.

Já vi este padrão em produção: a equipa separa “users service”, “billing service” e “notifications service”, mas todos continuam a precisar dos mesmos dados. Resultado: ou partilham a mesma base de dados, violando a independência dos serviços, ou duplicam dados sem uma estratégia de sincronização decente.

As duas opções doem.

Base de dados partilhada entre microserviços parece prática no início. Mas se o serviço A lê tabelas do serviço B, não tens microserviços. Tens um monólito distribuído, que é pior do que um monólito normal. Agora tens os custos de rede e deploys independentes sem independência real.

Bases de dados separadas exigem eventos, contratos, idempotência e reconciliação. Por exemplo, se o billing precisa de saber o email do utilizador, vais copiar esse dado? Vais consultar o serviço de utilizadores em runtime? Vais reagir a um evento UserEmailChanged? O que acontece se o evento falhar? Como corriges divergências?

O padrão outbox é uma resposta séria para este problema. Em vez de gravar dados e publicar evento em duas operações separadas, guardas o evento na mesma transacção da alteração principal. Depois, um worker publica o evento. Martin Fowler descreve bem padrões relacionados em https://martinfowler.com/articles/201701-event-driven.html, e a ideia também aparece em arquitecturas event-driven usadas com Kafka, RabbitMQ ou filas geridas.

Mas repara: se já estás a falar de outbox, retries, dead letters, consumidores idempotentes e reconciliação, tens de perguntar se esses mecanismos são justificados para 10 utilizadores.

Em muitos casos, a decisão mais madura é manter uma base de dados única, com schemas ou convenções por domínio, e preparar o terreno. PostgreSQL aguenta volumes muito maiores do que a maioria das startups atinge nos primeiros anos. Com índices correctos, queries medidas e connection pooling, 300 requests por segundo não é ficção num monólito bem escrito. O teu gargalo com 10 utilizadores não será esse.

Como decidir: uma grelha simples e brutal

Antes de migrar, responde a estas perguntas com dados, não com ansiedade.

PerguntaSe a resposta for “não”
Tens p95 acima de 300 ms em endpoints críticos por causa de um módulo específico?Não migres. Optimiza queries, cache e jobs.
Tens p99 acima de 1 s por chamadas internas bloqueantes?Primeiro remove chamadas desnecessárias e mede.
Tens mais de 5 deploys por dia bloqueados por conflitos entre equipas?Com equipa pequena, o problema pode ser processo, não arquitectura.
Tens módulos com necessidades de escala 10x diferentes?Se não, um processo separado pode chegar.
Tens requisitos legais que obrigam a isolamento?Se não, evita fragmentar dados cedo.
Tens observabilidade mínima com logs estruturados, métricas e tracing?Sem isto, microserviços vão piorar incidentes.

Métricas mínimas antes de considerar microserviços:

  • p50, p95 e p99 por endpoint
  • taxa de erro 4xx e 5xx
  • tempo médio e máximo dos jobs
  • tamanho da base de dados, por exemplo 10 GB, 100 GB ou 1 TB
  • número de conexões activas no PostgreSQL
  • custo mensal por ambiente
  • tempo médio para diagnosticar um incidente
  • tempo de deploy e rollback

Se não tens estes números, estás a decidir arquitectura por sensação. Isso é caro.

Para observabilidade, OpenTelemetry é hoje uma boa base. A documentação oficial está em https://opentelemetry.io/docs/. Não precisas de uma plataforma caríssima no primeiro mês, mas precisas de logs com correlation IDs, métricas úteis e traces nos fluxos críticos.

Também deves olhar para contratos de API. Se começares a separar serviços, define OpenAPI 3.1 para HTTP ou Protobuf para gRPC. Sem contrato, cada deploy vira uma aposta. A especificação OpenAPI está em https://spec.openapis.org/oas/latest.html.

Um caminho de migração sensato

A boa migração para microserviços começa muito antes de criares o primeiro serviço.

Primeiro, limpa o monólito. Separa módulos, remove dependências circulares, centraliza permissões e cria interfaces internas. Se isto for impossível, microserviços não vão resolver. Vão apenas distribuir a confusão.

Segundo, move trabalho lento para background jobs. Um endpoint que gera relatórios, sincroniza stock ou chama APIs externas não deve bloquear o pedido do utilizador. Com 10 utilizadores, esta alteração costuma dar mais ganhos do que uma reescrita arquitectural.

Terceiro, cria eventos internos. Não precisam de sair do processo no primeiro dia. O objectivo é tornar explícito que “pagamento confirmado” dispara “actualizar subscrição”, “emitir recibo” e “enviar email”. Quando isto está claro, podes trocar o mecanismo interno por uma fila real.

Quarto, mede. Se um módulo específico consome 80% do CPU, 90% do tempo de resposta ou exige deploys independentes constantes, tens um candidato. Caso contrário, tens apenas vontade de mexer em arquitectura.

Quinto, extrai um serviço pequeno e com fronteira óbvia. Bons candidatos: processamento de ficheiros, notificações, webhooks, motor de pesquisa, geração de PDFs. Maus candidatos iniciais: utilizadores, permissões e billing. Estes tendem a estar ligados a tudo.

Sexto, assume o custo completo. Um serviço novo precisa de pipeline, health checks, logs, métricas, alertas, documentação, testes de contrato, gestão de segredos e plano de rollback. Se não tens apetite para isto, não tens apetite para microserviços.

Uma regra prática: se não consegues operar dois serviços com confiança às 03:00, não cries dez.

Conclusão

Com 10 utilizadores, microserviços raramente são a decisão certa. Um monólito modular, bem medido e com jobs assíncronos dá mais velocidade e menos risco. Migra apenas quando houver dados, fronteiras claras e uma razão operacional forte.

Se estás a enfrentar um problema parecido, marca uma conversa em https://impact-origin.com/agendamento.

Impact OriginGostaste deste artigo?Na Impact Origin ajudamos fundadores e equipas a construir e escalar software à medida, do MVP da startup ao próximo passo. Se tens um projeto em mente, vamos falar.