📄 O que são ADRs
Architecture Decision Records são documentos curtos e estruturados que registram decisões arquiteturais significativas: o contexto, a decisão tomada e suas consequências. Vivem no repositório junto ao código, são versionados com git e revisados como qualquer outro artefato. São a “memória institucional” que impede que cada novo desenvolvedor redescubra (e frequentemente reverta) decisões anteriores.
💡 Conceito Principal
Um ADR tem quatro elementos fundamentais:
- •Contexto — Qual problema motivou a decisão? Quais forças estão em jogo?
- •Decisão — O que foi escolhido e por quê. Sempre com “because”.
- •Consequências — O que melhora e o que piora com essa decisão
- •Status — Proposed, Accepted, Deprecated ou Superseded
📊 Caso Real: Spotify
O Spotify tem mais de 1.000 ADRs públicos internamente e mediu o impacto da prática:
- 40% menos discussões repetidas sobre decisões já tomadas
- Onboarding 30% mais rápido para novos desenvolvedores
- Consistência entre squads que trabalham em domínios similares
- Rastreabilidade completa — sempre se sabe por que algo foi decidido daquela forma
✓ O que FAZER
- ✓Tratar ADRs como código — versionado, revisado, mergeado
- ✓Escrever ADRs no momento da decisão, não depois
- ✓Incluir alternativas rejeitadas e os motivos
✗ O que NÃO fazer
- ✗Documentar na Confluence e esperar que alguém leia
- ✗Escrever ADRs com 10 páginas — ideal é 1 página
- ✗Documentar depois de implementar — o contexto já se perdeu
💡 Dica Prática
Comece hoje: crie uma pasta docs/adr/ no seu repositório e escreva o primeiro ADR sobre uma decisão recente. Não precisa ser perfeito — ADR ruim é melhor que nenhum ADR. O hábito se constrói com a prática.
✍️ Como Escrever um Bom ADR
Um bom ADR segue o template de Michael Nygard: Título, Data, Status, Contexto, Decisão, Consequências. A chave é o “because” — a decisão sem justificativa não é um ADR, é um anúncio. ADRs ruins dão falsa sensação de documentação e são piores que nenhum ADR.
📋 Template de ADR (Michael Nygard)
# ADR-001: Usar PostgreSQL como banco primário
Status: Accepted
Date: 2024-01-15
Deciders: Time de Plataforma
## Contexto
Precisamos de um banco relacional com suporte a JSON, full-text search e extensões geoespaciais...
## Decisão
Usaremos PostgreSQL because atende todos os requisitos e o time já tem expertise...
## Consequências
+ Ecossistema maduro, comunidade ativa
- Precisamos de expertise em tuning de PostgreSQL
✓ Bom ADR
- ✓“Escolhemos PostgreSQL porque precisamos de transações ACID e o time tem expertise”
- ✓Inclui alternativas rejeitadas: MongoDB descartado por falta de transações multi-document
- ✓Cabe em uma página — conciso e direto
✗ Mau ADR
- ✗“Decidimos usar PostgreSQL” — sem contexto nem justificativa
- ✗10 páginas de análise comparativa que ninguém lê
- ✗Escrito 6 meses depois da decisão — contexto perdido
📊 Formatos Populares
- Nygard (original) — Título, Status, Contexto, Decisão, Consequências
- MADR (Markdown ADR) — Adiciona Alternativas Consideradas e Prós/Contras estruturados
- Y-Statement — “No contexto de X, enfrentando Y, decidimos Z para atingir W, aceitando Q”
- Lightweight ADR — Apenas 3 seções: Problema, Decisão, Impacto
💡 Dica Prática
Use o formato MADR se seu time gosta de estrutura, ou Nygard se prefere simplicidade. O formato importa menos que a consistência. Escolha um e use para todos os ADRs — não misture formatos no mesmo projeto.
🔎 Quando Criar um ADR
Não documente tudo, documente o que importa. ADRs são para decisões significativas — escolha de banco de dados, estilo arquitetural, protocolo de comunicação, estratégia de deploy. Over-documentation mata a prática tão rápido quanto a ausência de documentação.
💡 Regra dos 4 Critérios
Escreva um ADR se a decisão atende pelo menos um desses critérios:
- •É difícil de reverter — Mudar de banco de dados depois de 2 anos custa caro
- •Afeta múltiplos times — Padrão de comunicação entre serviços, por exemplo
- •Tem trade-offs não-óbvios — Se a resposta é óbvia, não precisa de ADR
- •Alguém vai perguntar “por quê?” daqui a 6 meses
⚠️ Armadilha: Over-Documentation
Times que documentam tudo em ADRs geram fadiga e a prática morre em semanas:
- •“ADR-042: Usar tabs em vez de espaços” — Não. Isso é linter config.
- •“ADR-043: Usar Jest para testes” — Talvez. Só se houve debate real.
- •“ADR-044: Usar Event Sourcing para pagamentos” — Sim! Decisão com alto impacto e trade-offs.
💡 Dica Prática
Teste mental rápido: “Se um dev novo entrar no time daqui a 1 ano, essa decisão vai confundi-lo?” Se sim, escreva um ADR. Se a decisão é auto-evidente pelo código, economize o tempo.
📂 Organizando no Repositório
ADRs devem viver junto ao código no repositório. Documentação na Confluence, Google Docs ou wikis internas é onde decisões vão para morrer. No repositório, o ADR aparece no PR review, no blame, no log — é parte do fluxo natural de desenvolvimento.
📁 Estrutura Recomendada
projeto/
├── docs/
│ ├── adr/
│ │ ├── 0001-use-postgresql.md
│ │ ├── 0002-adopt-event-sourcing-for-payments.md
│ │ ├── 0003-use-grpc-for-internal-communication.md
│ │ └── README.md (index com links)
│ └── architecture/
│ └── c4-diagrams/
├── src/
└── ...
📊 Ferramentas de ADR
- adr-tools (CLI) —
adr new "Use PostgreSQL"cria o arquivo com template e numeração automática - Log4brains — Gera site estático navegável a partir dos ADRs Markdown do repositório
- ADR Manager (VS Code) — Extensão para criar, visualizar e gerenciar ADRs direto no editor
- GitHub/GitLab templates — Template de PR que exige link para ADR quando há mudança arquitetural
✓ O que FAZER
- ✓Numerar sequencialmente: 0001, 0002, 0003
- ✓Linkar ADRs nos PRs que implementam a decisão
- ✓Manter um README index com todos os ADRs e status
✗ O que NÃO fazer
- ✗Guardar ADRs na Confluence — morrem em semanas
- ✗Usar nomes genéricos como “decision-1.md”
- ✗Deletar ADRs antigos — deprecie, não apague
🔄 Lifecycle de um ADR
ADRs têm ciclo de vida: nascem como Proposed, são aceitos ou rejeitados, e eventualmente podem ser Superseded por uma nova decisão. O ADR antigo não é “errado” — era certo para o contexto da época. A história completa fica preservada.
🔄 Fluxo de Status
🔴 Proposed
ADR criado como PR. Time revisa, comenta, sugere alterações. Funciona como um RFC (Request for Comments) assíncrono.
🟢 Accepted
Time concorda com a decisão. PR mergeado. A partir daqui, a decisão é a referência oficial.
🟡 Deprecated
A decisão não é mais relevante (ex: tecnologia descontinuada). Mantido para histórico.
🔵 Superseded
Substituído por um novo ADR. Ex: “ADR-0023 substitui ADR-0005”. Link bidirecional entre os dois.
📊 Exemplo de Superseding
- ADR-0005 (2022) — “Usar REST para todas as APIs” — Status: Superseded by ADR-0023
- ADR-0023 (2024) — “Usar gRPC para comunicação serviço-a-serviço” — Status: Accepted
- Contexto da mudança — Latência p99 entre serviços ultrapassou SLO de 50ms com REST/JSON. gRPC com protobuf reduziu para 12ms.
A história mostra que REST era correto em 2022 (time pequeno, poucos serviços) e gRPC é correto agora (20 serviços, latência crítica).
💡 Dica Prática
Nunca delete um ADR. ADRs superseded são história valiosa. Eles mostram como o pensamento do time evoluiu e por que decisões anteriores faziam sentido no contexto original. Marque como superseded e adicione o link para o ADR substituto.
🗣️ Ferramenta de Comunicação
ADRs não são só documentação — são uma ferramenta de alinhamento assíncrono. Um ADR com status “Proposed” é um RFC que o time revisa antes da implementação. Isso elimina reuniões desnecessárias e dá a todos a chance de contribuir, independente do fuso horário.
💡 ADR como RFC
O fluxo de ADR como ferramenta de comunicação:
- •Autor propõe — Cria branch, escreve ADR, abre PR
- •Time comenta — Perguntas, sugestões, preocupações — tudo registrado no PR
- •Ajustes são feitos — Iterações até consenso (ou consent)
- •Merge = aceito — A decisão é oficial quando o PR é mergeado
📊 Caso Real: ThoughtWorks
O ThoughtWorks usa ADRs como RFCs e eliminou 80% das reuniões de decisão arquitetural:
- Antes: Reuniões de 1h com 8 pessoas para discutir cada decisão = 8h de trabalho
- Depois: ADR escrito em 30min, revisado assincronamente = ~2h de trabalho total
- Bônus: Introverted devs que não falam em reuniões contribuem mais por escrito
- Resultado: Decisões melhores, mais inclusivas, e 75% mais rápidas
✓ O que FAZER
- ✓Definir período de comentários (ex: 3 dias úteis)
- ✓Usar consent, não consensus — “alguém discorda?” vs. “todos concordam?”
- ✓Ter path de escalação para impasses
✗ O que NÃO fazer
- ✗Usar ADR para justificar decisão já tomada
- ✗Ignorar comentários e mergear unilateralmente
- ✗Deixar ADR “Proposed” por semanas sem resolução
📊 Métricas e Revisão
Decisões envelhecem. O que era correto com 10 usuários pode ser errado com 10 milhões. Revisar ADRs periodicamente à luz de novos dados garante que a arquitetura evolui com o sistema. Architecture Fitness Functions automatizam essa verificação.
💡 Estratégias de Revisão
- •Review trimestral — Passar pelos ADRs ativos uma vez por quarter e validar se ainda fazem sentido
- •Trigger-based — Revisar quando uma métrica ultrapassa threshold (ex: latência > SLO)
- •Incident-driven — Todo post-mortem verifica se algum ADR precisa ser revisitado
- •Scale-triggered — Ao atingir milestones de escala (10x usuários, novo mercado)
📊 Fitness Functions na Prática
Testes automatizados que verificam se a arquitetura ainda atende seus atributos de qualidade:
- ArchUnit (Java) — “Nenhum controller importa repositório diretamente” — se alguém viola, o build quebra
- NetArchTest (.NET) — Mesma ideia para ecossistema .NET
- Performance budgets — CI falha se bundle size > 200KB ou se p99 > 200ms
- Dependency checks — Alertas se dependências circulares forem introduzidas
📋 Checklist de Revisão Trimestral
- ☐A decisão ainda resolve o problema original?
- ☐Os trade-offs documentados se confirmaram?
- ☐Surgiram alternativas melhores desde então?
- ☐O contexto mudou significativamente (escala, time, requisitos)?
- ☐Houve incidentes relacionados a essa decisão?
💡 Dica Prática
Adicione ao template do ADR um campo “Review trigger”: uma condição que, quando atingida, sinaliza que é hora de revisitar. Ex: “Revisitar se ultrapassarmos 10k req/s” ou “Revisitar se o time crescer além de 15 pessoas”.
📋 Resumo do Módulo
Próximo Módulo:
2.5 - 🔄 Migração e Evolução — Strangler Fig, Feature Flags e estratégias para evoluir sistemas sem quebrar