System Design: um guia passo a passo para desenhar sistemas escaláveis

23 de fevereiro de 2026

Seja numa entrevista técnica ou no trabalho, a pergunta chega: "Como você desenharia esse sistema?". A maioria dos devs abre o Miro, começa a desenhar caixinhas e perde o fio da meada em 5 minutos. Neste post, vou te mostrar um processo claro para conduzir um System Design de qualidade — do zero até a arquitetura final.

Por que System Design importa?

Escrever código bom é necessário. Mas antes de escrever qualquer linha, alguém precisa decidir como o sistema vai funcionar como um todo — quais componentes existem, como eles se comunicam, onde os dados vivem, o que acontece quando algo falha.

Essa é a essência do System Design: tomar decisões arquiteturais conscientes antes que o custo de mudança seja alto demais.

Um sistema mal desenhado no início vira dívida técnica para sempre. Um sistema bem desenhado cresce com elegância.

O processo em 6 passos

Passo 1 — Entenda o problema antes de qualquer coisa

O erro mais comum é sair desenhando sem entender o que está sendo pedido. Antes de abrir qualquer ferramenta, faça perguntas.

Perguntas essenciais:

  • Qual o problema de negócio que esse sistema resolve?
  • Quem são os usuários e como eles interagem com o sistema?
  • Quais são os casos de uso principais? (as 3 a 5 ações mais importantes)
  • Existe alguma restrição técnica ou de negócio que devo considerar?

Nunca assuma. Sempre pergunte. Um sistema de agendamentos para um petshop local tem requisitos completamente diferentes de um sistema de agendamentos para uma rede nacional.

Passo 2 — Defina os requisitos

Com o problema entendido, separe os requisitos em dois tipos:

Requisitos funcionais — o que o sistema faz:

  • Usuários podem se cadastrar e fazer login
  • É possível criar, editar e cancelar agendamentos
  • O sistema envia notificações de confirmação

Requisitos não-funcionais — como o sistema se comporta:

  • Quantos usuários simultâneos o sistema precisa suportar?
  • Qual a latência aceitável para as operações críticas?
  • O sistema precisa estar disponível 24/7 ou tem janelas de manutenção?
  • Os dados precisam de consistência forte ou consistência eventual é aceitável?

⚠️ Os requisitos não-funcionais são os que mais influenciam as decisões arquiteturais — e os mais esquecidos por devs júnior.

Passo 3 — Estime a escala

Antes de escolher qualquer tecnologia ou padrão, você precisa entender a ordem de grandeza do sistema.

Perguntas de escala:

  • Quantos usuários ativos por dia/mês?
  • Qual o volume de leituras vs escritas? (ex: 90% leitura, 10% escrita)
  • Qual o tamanho médio dos dados? (ex: cada registro tem ~1KB)
  • Qual o crescimento esperado nos próximos 12 meses?

Essas estimativas guiam decisões como: preciso de cache? preciso de múltiplos bancos? preciso de CDN? preciso de filas de mensagens?

Um sistema com 100 usuários e um com 10 milhões de usuários têm arquiteturas completamente diferentes — mesmo resolvendo o mesmo problema.

Passo 4 — Desenhe a arquitetura de alto nível

Agora sim você abre o Miro. Mas com propósito.

Comece simples — um diagrama com os componentes principais e como eles se conectam:

┌─────────┐ ┌─────────────┐ ┌──────────────┐ Usuário │ Client │──────▶ │ API Gateway│──────▶│ Serviços │ │ Web/ │ │ (entrada │ │ (negócio) │ │ Mobile │ │ única) │ └──────┬───────┘ └─────────┘ └─────────────┘ │ ┌───────▼──────┐ │ Banco de │ │ Dados │ └──────────────┘

A partir desse esqueleto, vá adicionando camadas conforme a necessidade:

Cache: se as leituras são frequentes e os dados mudam pouco, adicione uma camada de cache (Redis, Memcached) entre os serviços e o banco.

Fila de mensagens: se há operações assíncronas ou comunicação entre serviços, adicione uma fila (RabbitMQ, Kafka, SQS).

CDN: se há conteúdo estático ou arquivos de mídia, adicione uma CDN para distribuir geograficamente.

Load Balancer: se há múltiplas instâncias de um serviço, adicione um balanceador de carga na frente.

Passo 5 — Aprofunde os componentes críticos

Depois do alto nível, escolha os componentes mais críticos ou complexos e aprofunde o design deles.

Banco de dados: SQL ou NoSQL? Por quê? Como os dados são modelados? Precisa de replicação? De sharding?

Autenticação: JWT? OAuth? Sessão? Como tokens são invalidados?

Comunicação entre serviços: REST? gRPC? Eventos assíncronos? Qual o contrato entre eles?

Consistência de dados: se há múltiplos bancos (CQRS, microsserviços), como garantir que os dados estejam sincronizados?

Você não precisa aprofundar tudo — foque no que é mais crítico para o negócio e nos pontos onde uma decisão errada seria mais difícil de reverter.

Passo 6 — Identifique os pontos de falha e como mitigá-los

Todo sistema vai falhar em algum momento. A diferença entre um sistema bom e um ruim é saber onde vai falhar e ter um plano.

Perguntas para esse passo:

  • O que acontece se o banco principal cair? (replicação, fallback)
  • O que acontece se um serviço ficar lento? (timeout, circuit breaker)
  • O que acontece se a fila encher? (dead letter queue, alertas)
  • Como o sistema se recupera de uma falha parcial sem perder dados?

Ferramentas importantes nessa etapa: health checks, circuit breakers, retries com backoff exponencial, monitoramento e alertas.

Um sistema que falha graciosamente é muito melhor do que um que não falha — até o dia que falha tudo de uma vez.

Os pilares de um bom System Design

Independente do sistema, todo bom design equilibra esses pilares:

Escalabilidade — o sistema aguenta crescer sem refatoração completa? Escala horizontal ou vertical?

Disponibilidade — qual o SLA? O sistema tolera falhas parciais sem derrubar tudo?

Consistência — os dados são sempre consistentes ou há janelas de inconsistência aceitáveis?

Manutenibilidade — um dev novo consegue entender e evoluir o sistema? O código e a arquitetura contam a mesma história?

Custo — a arquitetura é justificável financeiramente para o estágio atual do produto?

Esses pilares vivem em tensão constante. Aumentar disponibilidade geralmente aumenta custo. Aumentar consistência pode reduzir performance. O trabalho do arquiteto é encontrar o equilíbrio certo para o contexto.

Os erros mais comuns

Over-engineering desde o início: microsserviços, CQRS, Event Sourcing e Kafka para um sistema com 50 usuários é desperdício de tempo e dinheiro. Comece simples e evolua quando a dor for real.

Ignorar os requisitos não-funcionais: projetar o sistema sem saber o volume esperado é como construir uma ponte sem saber o peso dos veículos que vão passar.

Escolher tecnologia antes de entender o problema: "vamos usar Kafka" não é uma decisão de arquitetura — é uma escolha de ferramenta. Primeiro entenda o problema, depois escolha a ferramenta.

Não pensar em falhas: todo componente externo vai falhar em algum momento. Design que não contempla falhas não está completo.

Como tudo da série se encaixa aqui

Se você acompanhou os posts anteriores, o System Design é onde tudo se conecta:

  • POO e SOLID guiam o design interno de cada componente
  • Clean Architecture organiza as camadas dentro de cada serviço
  • DDD define os Bounded Contexts que viram os serviços do sistema
  • Microsserviços é o estilo arquitetural para sistemas distribuídos
  • CQRS separa leitura e escrita quando a escala exige
  • GoF Patterns resolve problemas pontuais dentro dos componentes

O System Design é a visão macro. Todo o resto é como você implementa essa visão com qualidade.

GitHub
LinkedIn