# System design: 20 conceitos que separam júnior de sênior

> Published 2026-10-12T22:57:52.781Z on https://www.crazystack.com.br/pt/p/system-design-20-conceitos-que-separam-junior-de-senior/
> Source video: https://www.youtube.com/watch?v=7lH36O1Pudg

System design reúne os vinte conceitos que separam um dev júnior de um sênior. A lista começa em idempotência e termina em rate limiting e cold start, passando por CAP, back pressure e migração em duas etapas, com o erro real que cada conceito evita e uma fonte primária para aprofundar.

## O que é system design e por que ele separa júnior de sênior

System design é o conjunto de decisões sobre consistência, disponibilidade, mensageria, carga e evolução de dados que define se um sistema sobrevive a falhas. A diferença entre júnior e sênior aparece nesses vinte conceitos: o sênior reconhece o problema antes de escrever o código, o júnior descobre o problema quando a produção cai.

O canal Augusto Galego publicou em 1º de julho de 2026 o vídeo "20 Conceitos que Separam Devs Júnior de Sênior", um overview que funciona como roadmap de estudo. O próprio autor avisa que o formato é expositivo, não um curso: cada conceito renderia meia hora de explicação.

O valor real da lista é epistemológico. Você só consegue estudar aquilo que sabe que não sabe; o problema mora no desconhecimento invisível. Uma lista de conceitos vira um checklist de lacunas antes da próxima entrevista técnica ou revisão de arquitetura.

### Onde cada conceito se aplica

Idempotência e transações distribuídas aparecem em pagamentos e reservas. CAP, consistência eventual e réplicas de leitura aparecem em qualquer banco replicado. Exactly-once, back pressure e thundering herd aparecem em mensageria e picos de tráfego.

Migração, evolução de schema e rate limiting aparecem no ciclo de vida do dado e da API. São camadas diferentes do mesmo sistema, e por isso o guia cobre os vinte conceitos juntos em vez de isolá-los.

## Idempotência e transações distribuídas

Idempotência garante que repetir a mesma operação produza um único efeito: o segundo Pix idêntico não passa. A implementação comum monta uma chave de idempotência a partir de atributos da requisição, como nome, contas e valor, calcula um hash desses campos e guarda o resultado em cache com um TTL de poucos minutos. Como o hash se repete, a segunda requisição é bloqueada.

A documentação da [Stripe](https://docs.stripe.com/api/idempotent_requests), plataforma de pagamentos, descreve essa mesma mecânica com a chave enviada pelo cliente e retenção de 24 horas. O detalhe importa: sem uma chave determinística e sem o armazenamento com expiração, a proteção não existe.

Transações distribuídas surgem quando uma compra envolve serviços que você não controla, como companhia aérea, hotel e locadora. Ou o preço e a disponibilidade de todos se mantêm até o commit, ou o cliente paga por algo que não existe mais. O padrão saga resolve isso com transações locais encadeadas e compensações explícitas para cada passo que falha.

O [padrão saga](https://microservices.io/patterns/data/saga.html) troca atomicidade forte por consistência eventual gerenciada. Cada serviço confirma sua parte e publica um evento; se um passo falha, uma ação compensatória desfaz o efeito anterior. É a diferença entre um rollback único e uma coreografia de desfazimentos, e é isso que torna o conceito difícil na prática.

## Consistência eventual, réplicas de leitura e CAP

Consistência eventual significa que réplicas diferentes convergem para o mesmo valor sem garantir que estejam iguais em qualquer instante. O número de views de um vídeo visto no Brasil, na Alemanha e na China tende a coincidir depois de algum tempo, mas não existe promessa de igualdade a cada leitura.

O desenho típico separa um banco primário de escrita e várias réplicas de leitura, porque aplicações leem muito mais do que escrevem. Você pode confirmar o write ao usuário e sincronizar depois, ou esperar a sincronização e só então responder. A escolha define quanto de dado desatualizado o usuário aceita ver.

O [teorema CAP](https://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf), proposto por Eric Brewer e formalizado por Seth Gilbert e Nancy Lynch em 2002, afirma que um sistema distribuído não entrega consistência e disponibilidade ao mesmo tempo quando ocorre uma partição de rede. Como a partição é imposta pela realidade, a decisão prática fica entre negar escritas ou aceitá-las e reconciliar depois.

Em 2012, Brewer revisou o próprio enunciado e escreveu que "2 de 3" é enganoso, porque as escolhas são muito mais granulares do que o slogan sugere. Vale consultar essa revisão antes de citar CAP em entrevista.

### Réplicas de leitura e o preço da latência

Réplicas de leitura reduzem carga no primário e aproximam os dados do usuário. Em troca, você aceita read-your-writes inconsistente por uma janela curta. Em um checkout, essa janela pode fazer o cliente ver um saldo antigo logo após pagar, o que exige roteamento da leitura para o primário em fluxos críticos.

## Entrega de mensagens: exactly-once, at-least-once e at-most-once

Sistemas de mensageria precisam escolher entre entregar ao menos uma vez, no máximo uma vez ou exatamente uma vez, e nenhuma dessas opções é gratuita. Exactly-once é a mais difícil e a mais cara de garantir em um sistema distribuído, porque exige coordenação entre produtor, broker e consumidor.

A [documentação do Apache Kafka](https://kafka.apache.org/documentation/), plataforma de streaming de eventos, explica que a semântica exactly-once é obtida com produtores idempotentes combinados a transações. Fora desse arranjo, a garantia prática é at-least-once, e o consumidor precisa ser idempotente para absorver duplicatas.

Essa combinação explica por que idempotência aparece tanto em mensageria. Se a entrega pode repetir, o consumidor precisa reconhecer a repetição. At-least-once com consumidor idempotente resolve a maioria dos casos reais com muito menos custo que exactly-once ponta a ponta.

### Quando escolher cada semântica

At-most-once serve para telemetria e métricas, onde perder uma amostra não muda a decisão. At-least-once serve para quase tudo que precisa de garantia, desde que o consumidor seja idempotente. Exactly-once fica restrito a fluxos financeiros e de contabilidade, onde a duplicação tem custo direto e mensurável.

## Back pressure, thundering herd, hot shard e circuit breaker

Back pressure é o mecanismo que permite ao consumidor avisar o produtor de que ele está cheio e precisa desacelerar. Sem essa comunicação, um produtor que gera 20 itens por segundo contra um consumidor que processa 5 por segundo enche memória, fila ou disco até o sistema estourar.

O [Reactive Streams](https://www.reactive-streams.org/), especificação de processamento assíncrono com controle de demanda, formaliza esse contrato com um número de itens solicitados pelo consumidor. Filas com limite e descarte controlado também funcionam como amortecedor, mas só adiam o problema se o produtor nunca desacelera.

Thundering herd acontece quando muitos clientes repetem a tentativa ao mesmo tempo depois de uma falha, como uma cache key popular que expira e joga todo o tráfego no banco. O [problema do rebanho trovejante](https://en.wikipedia.org/wiki/Thundering_herd_problem) tem origem conhecida em sistemas operacionais e aparece igualmente em cache e em retry sem jitter.

Quando uma partição concentra uma celebridade, ela vira um hot shard. O [artigo da AWS sobre partições quentes](https://docs.aws.amazon.com/whitepapers/latest/aws-best-practices-dynamodb-design/designing-partitions.html) mostra que a solução passa por distribuir a chave, escrever com sufixo aleatório ou separar o tráfego do item popular.

O circuit breaker fecha o circuito quando um serviço dependente para de responder. Em vez de acumular requisições que vão falhar, o sistema desvia para um caminho alternativo ou resposta degradada. A ideia vem do livro *Release It!*, de Michael Nygard, e virou padrão em bibliotecas de resiliência.

### Retry precisa de jitter

Retry sem aleatoriedade sincroniza todos os clientes no mesmo instante e recria o thundering herd. Exponential backoff com jitter espalha as tentativas no tempo e reduz o pico no recurso que acabou de voltar. O [artigo da AWS sobre backoff e jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) compara as estratégias e mostra por que a versão com jitter é a recomendada.

## Feature flags, evolução de schema e versionamento

Feature flags permitem liberar uma funcionalidade para um grupo de usuários sem novo deploy. Uma flag como has_beta_checkout liga o checkout novo só para os clientes que aceitaram participar do beta, e serve para rollout gradual, teste A/B e controle de acesso.

O [guia da Unleash sobre feature flags](https://docs.getunleash.io/), ferramenta de gerenciamento de flags, descreve o ciclo completo: criar, liberar, medir e remover. A remoção é a parte esquecida. Flags antigas viram ramificações mortas no código e transformam qualquer leitura em arqueologia.

Evolução de schema é mudar um campo, um evento ou um contrato sem quebrar quem consome. Se você emite o evento "cliente comprou" e passa a emitir "cliente comprou com desconto X", todos os consumidores precisam continuar funcionando durante a transição. Isso exige versionamento explícito e período de compatibilidade.

O [formato Avro](https://avro.apache.org/docs/), usado em pipelines de eventos, trata evolução de schema como cidadã de primeira classe, com regras de compatibilidade entre versões. A regra prática é adicionar campos opcionais e nunca reaproveitar um nome com outro significado.

### Flags e schema mudam juntos

Uma flag que muda o formato do evento emitido afeta todos os consumidores, não só a interface. Antes de ligar a flag, verifique se os consumidores aguentam o novo payload. O mesmo cuidado vale para a API: versione o contrato e mantenha o antigo funcionando pelo tempo combinado.

## Migração em duas etapas: o erro dos 7 minutos

Adicionar um campo obrigatório e enviá-lo no mesmo deploy derruba a produção, porque o banco precisa preencher o campo retroativamente em toda a tabela antes de aceitar a nova regra. O lock resultante bloqueia as requisições. Foi exatamente esse erro que deixou um sistema inutilizável por sete minutos, conforme relato do autor do vídeo.

O [artigo do PostgreSQL sobre ALTER TABLE](https://www.postgresql.org/docs/current/sql-altertable.html) confirma que adicionar uma coluna com valor padrão e restrição NOT NULL exige varredura completa da tabela. Em tabelas grandes, esse trabalho mantém um lock e trava operações concorrentes.

A correção é dividir a mudança em duas etapas. Primeiro você cria o campo como opcional e aceita nulos. Depois preenche os registros existentes em lotes, processo conhecido como backfill. Só quando o preenchimento termina e o código passa a enviar o campo em toda escrita você aplica a restrição de obrigatoriedade.

### As ferramentas de migração em escala

Backfill em lotes evita uma transação gigante que segura o lock por minutos. Dual writes escrevem na tabela antiga e na nova durante a transição, permitindo comparar resultados. Shadow tables espelham o tráfego de escrita para a nova estrutura antes de trocar a leitura, o que valida a migração com dados reais sem risco para o usuário.

Ferramentas de migração online, como [pg_repack](https://reorg.github.io/pg_repack/) e [gh-ost](https://github.com/github/gh-ost), existem justamente para trocar a tabela sem manter lock prolongado. Você raramente vai precisar aplicar isso, mas reconhecer o cenário evita repetir o erro de sete minutos.

## Rate limiting e cold start

Rate limiting define quantas requisições um cliente pode fazer em um intervalo, e existem quatro algoritmos clássicos. Fix window conta requisições dentro de uma janela fixa e reinicia no começo dela. Sliding window desliza o intervalo continuamente, o que suaviza a passagem de uma janela para outra.

Token bucket enche um balde com tokens a uma taxa constante e consome um token por ação; quando o balde esvazia, o cliente espera o reabastecimento. Leaky bucket funciona parecido, mas libera o excedente em velocidade reduzida em vez de recusar de imediato, o que alisa o tráfego na saída.

A [documentação da Stripe sobre rate limits](https://docs.stripe.com/rate-limits) usa o algoritmo de token bucket e publica limites por modo de operação, o que mostra o desenho em produção. Já o [artigo da Cloudflare sobre rate limiting](https://blog.cloudflare.com/counting-things-a-lot-of-different-things/) compara os quatro algoritmos com as vantagens e as limitações de cada um.

Cold start é o atraso extra na primeira invocação de uma função serverless, quando o provedor precisa preparar o ambiente de execução. O [documento da AWS sobre cold start em Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html) explica o ciclo de vida do ambiente e lista as causas do atraso. Réplicas pré-aquecidas e menor tamanho de pacote reduzem o efeito, mas não o eliminam.

### Como escolher o algoritmo

Fix window é o mais simples e o mais fácil de estourar na virada da janela. Sliding window custa mais memória, mas distribui melhor. Token bucket aceita rajadas controladas e por isso é o favorito de APIs públicas. Leaky bucket serve quando você precisa de vazão estável, como em integrações com parceiros lentos.

## O que fazer com essa lista na prática

Esta lista funciona como checklist de lacunas. Você não precisa dominar os vinte conceitos ao mesmo tempo; precisa saber qual deles você não sabe explicar em uma frase, com um exemplo e um trade-off. Esse é o teste que separa o reconhecimento da compreensão.

Se você está se preparando para entrevistas, o [System Design Primer](https://github.com/donnemartin/system-design-primer), repositório de estudo mantido por Donne Martin, organiza esses mesmos temas em sequência com problemas de prática. O canal [Augusto Galego](https://www.youtube.com/@AugustoGalego) tem vídeos dedicados aos conceitos citados aqui.

Cursos e comunidades brasileiras também cobrem o tema. O [Bootcamp do Dev Doido](https://crazystack.com.br) e o [Crazystack Typescript](https://crazystack.com.br) são exemplos de formação com foco em stack e arquitetura; [Gustavo Dev Doido](https://crazystack.com.br) mantém esse material, e o [Skala Blog](https://skalablog.com) publica conteúdo técnico em português.

Antes de aplicar qualquer mudança em produção, faça a pergunta que os vinte conceitos respondem: o que acontece quando isso falha? Idempotência, circuit breaker, back pressure, migração em duas etapas e rate limiting são respostas diferentes para a mesma pergunta. Todos os links citados aqui levam à documentação oficial, e vale abrir cada um antes de decidir a implementação.

## Perguntas frequentes

- **O que é idempotência em system design?** É a propriedade que garante que repetir a mesma operação produza um único efeito. A implementação comum usa uma chave de idempotência derivada dos atributos da requisição, armazenada com expiração. Sem a chave, a segunda tentativa é tratada como uma operação nova.

- **Qual a diferença entre consistência eventual e consistência forte?** Consistência forte garante que toda leitura enxergue a última escrita confirmada. Consistência eventual aceita janelas de divergência entre réplicas e promete convergência com o tempo. A escolha depende de quanto dado desatualizado o fluxo tolera.

- **Por que exactly-once é mais caro de garantir?** Porque exige coordenação entre produtor, broker e consumidor dentro da mesma transação. Kafka oferece a garantia com produtores idempotentes e transações, mas fora desse arranjo a semântica prática é at-least-once com consumidor idempotente.

- **O que é back pressure e quando ela aparece?** É o aviso do consumidor ao produtor de que ele está sobrecarregado e precisa desacelerar. Aparece quando a taxa de produção supera a de consumo por tempo suficiente para encher memória, fila ou disco. Sem esse aviso, o sistema estoura.

- **Como fazer uma migração de banco sem derrubar a produção?** Divida a mudança em etapas: crie o campo como opcional, preencha os registros existentes em lotes e só depois aplique a restrição de obrigatoriedade. Adicionar um campo obrigatório direto exige varredura completa e segura um lock prolongado.

- **Qual a diferença entre hot shard e celebrity problem?** Hot shard é uma partição que recebe tráfego muito acima das outras. O celebrity problem é o caso em que a causa é uma única entidade popular, como um perfil famoso. A solução passa por distribuir a chave ou tratar o item popular separadamente.

- **Quando usar circuit breaker em vez de retry?** Use retry para falhas transitórias, com backoff e jitter. Use circuit breaker quando o serviço dependente está claramente indisponível e as tentativas só acumulam carga. Os dois padrões se combinam: o retry trata a falha curta, o breaker interrompe a falha longa.

- **O que causa o cold start em funções serverless?** O provedor precisa preparar o ambiente de execução antes de atender a primeira invocação, o que adiciona latência. O efeito depende do runtime, do tamanho do pacote e da frequência de chamadas. Réplicas pré-aquecidas reduzem, mas não removem o atraso.

## Transforme suas aulas e lives em artigo

A ideia central deste guia é simples: reconhecer o conceito antes que ele vire incidente. Você provavelmente já explicou vários deles em uma live, numa aula gravada ou numa call de revisão de arquitetura, e esse material continua preso no vídeo, difícil de consultar e impossível de pesquisar.

O [Skala Blog](https://skalablog.com) resolve exatamente esse gargalo. Você cola a URL do vídeo do YouTube, o sistema transcreve o conteúdo e gera um artigo estruturado, com seções, tabelas e perguntas frequentes, pronto para revisão e publicação.

[Source video](https://www.youtube.com/watch?v=7lH36O1Pudg)
