architecture-decision-records
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseArchitecture Decision Records (ADR)
架构决策记录(ADR)
An Architecture Decision Record captures the context, decision, and consequences of significant technical choices. ADRs prevent re-litigating settled decisions and preserve institutional knowledge.
"Architecture is the stuff that's hard to change. Document why you chose it." — Michael Nygard
架构决策记录用于记录重大技术选择的背景、决策内容及后果。ADR可避免对已确定的决策再次争论,并保留机构知识。
"Architecture is the stuff that's hard to change. Document why you chose it." — Michael Nygard
🎯 When to Write an ADR
🎯 何时编写ADR
| Situation | Write ADR? | Template |
|---|---|---|
| Choosing a database (PostgreSQL vs MongoDB) | ✅ Yes | MADR Full |
| Adopting a framework (React vs Vue) | ✅ Yes | MADR Full |
| REST vs GraphQL vs gRPC | ✅ Yes | MADR Full |
| Adding a new microservice | ✅ Yes | MADR Full |
| Choosing a cloud provider | ✅ Yes | MADR Full |
| Fixing a typo in config | ❌ No | — |
| Adding a linter rule | ⚠️ Maybe | MADR Minimal |
| Updating a dependency version | ⚠️ Maybe | Y-Statement |
Rule of thumb: If the decision will affect the team for >6 months, write an ADR.
| 场景 | 是否编写ADR? | 模板 |
|---|---|---|
| 选择数据库(PostgreSQL vs MongoDB) | ✅ 是 | MADR完整版 |
| 采用框架(React vs Vue) | ✅ 是 | MADR完整版 |
| REST vs GraphQL vs gRPC | ✅ 是 | MADR完整版 |
| 添加新微服务 | ✅ 是 | MADR完整版 |
| 选择云服务商 | ✅ 是 | MADR完整版 |
| 修复配置中的拼写错误 | ❌ 否 | — |
| 添加代码检查规则 | ⚠️ 可能 | MADR精简版 |
| 更新依赖版本 | ⚠️ 可能 | Y-Statement |
经验法则: 如果决策会影响团队超过6个月,就编写ADR。
📝 MADR 4.0.0 Template (Full)
📝 MADR 4.0.0模板(完整版)
MADR (Markdown Architectural Decision Records) is the industry standard. Version 4.0.0 was released September 2024.
markdown
---
status: proposed | accepted | rejected | deprecated | superseded by ADR-0012
date: 2024-01-15
decision-makers: [@alice, @bob]
consulted: [@charlie, @diana]
informed: [@team-backend]
---MADR(Markdown架构决策记录)是行业标准。4.0.0版本于2024年9月发布。
markdown
---
status: proposed | accepted | rejected | deprecated | superseded by ADR-0012
date: 2024-01-15
decision-makers: [@alice, @bob]
consulted: [@charlie, @diana]
informed: [@team-backend]
---Use PostgreSQL as Primary Database
Use PostgreSQL as Primary Database
Context and Problem Statement
Context and Problem Statement
We need a relational database for our e-commerce platform. The database must:
- Support ACID transactions for order processing
- Handle complex queries for reporting
- Scale to 10M+ products
- Have strong community support and tooling
We need a relational database for our e-commerce platform. The database must:
- Support ACID transactions for order processing
- Handle complex queries for reporting
- Scale to 10M+ products
- Have strong community support and tooling
Decision Drivers
Decision Drivers
- Data consistency: Orders and payments require ACID guarantees
- Query complexity: Product search, order history, analytics need JOINs
- Team expertise: Team has 5+ years PostgreSQL experience
- Operational cost: Managed service availability (AWS RDS, GCP Cloud SQL)
- Ecosystem: ORM support, migration tools, monitoring
- Data consistency: Orders and payments require ACID guarantees
- Query complexity: Product search, order history, analytics need JOINs
- Team expertise: Team has 5+ years PostgreSQL experience
- Operational cost: Managed service availability (AWS RDS, GCP Cloud SQL)
- Ecosystem: ORM support, migration tools, monitoring
Considered Options
Considered Options
- PostgreSQL
- MySQL
- MongoDB
- CockroachDB
- PostgreSQL
- MySQL
- MongoDB
- CockroachDB
Decision Outcome
Decision Outcome
Chosen option: "PostgreSQL", because it best satisfies our decision drivers:
- Full ACID compliance for financial transactions
- Advanced JSON support for flexible product attributes
- Excellent query planner for complex analytics
- Managed services available on AWS, GCP, Azure
- Team already proficient
Chosen option: "PostgreSQL", because it best satisfies our decision drivers:
- Full ACID compliance for financial transactions
- Advanced JSON support for flexible product attributes
- Excellent query planner for complex analytics
- Managed services available on AWS, GCP, Azure
- Team already proficient
Consequences
Consequences
- Good, because ACID transactions prevent data corruption in order processing
- Good, because JSONB columns allow flexible schema for product attributes without full NoSQL
- Good, because AWS RDS provides automated backups, failover, and patching
- Bad, because horizontal scaling requires read replicas or sharding (more complex than DynamoDB)
- Bad, because schema migrations require downtime or complex blue/green deployment
- Good, because ACID transactions prevent data corruption in order processing
- Good, because JSONB columns allow flexible schema for product attributes without full NoSQL
- Good, because AWS RDS provides automated backups, failover, and patching
- Bad, because horizontal scaling requires read replicas or sharding (more complex than DynamoDB)
- Bad, because schema migrations require downtime or complex blue/green deployment
Confirmation
Confirmation
- Validate: Run load test with 10M products + concurrent orders
- Revisit if: Write throughput exceeds 10K TPS or horizontal scaling becomes critical
- Validate: Run load test with 10M products + concurrent orders
- Revisit if: Write throughput exceeds 10K TPS or horizontal scaling becomes critical
Pros and Cons of the Options
Pros and Cons of the Options
PostgreSQL
PostgreSQL
- Good, because full ACID compliance and advanced SQL features
- Good, because JSONB provides document-like flexibility within relational structure
- Good, because mature ecosystem (PostGIS, full-text search, partitioning)
- Bad, because vertical scaling limits on single-node writes
- Bad, because schema changes require migration planning
- Good, because full ACID compliance and advanced SQL features
- Good, because JSONB provides document-like flexibility within relational structure
- Good, because mature ecosystem (PostGIS, full-text search, partitioning)
- Bad, because vertical scaling limits on single-node writes
- Bad, because schema changes require migration planning
MySQL
MySQL
- Good, because widely used, good performance for simple queries
- Good, because AWS Aurora provides excellent managed service
- Bad, because less advanced query planner for complex analytics
- Bad, because JSON support less mature than PostgreSQL JSONB
- Good, because widely used, good performance for simple queries
- Good, because AWS Aurora provides excellent managed service
- Bad, because less advanced query planner for complex analytics
- Bad, because JSON support less mature than PostgreSQL JSONB
MongoDB
MongoDB
- Good, because schema flexibility for rapidly changing product attributes
- Good, because horizontal scaling via sharding is native
- Bad, because eventual consistency unacceptable for financial transactions
- Bad, because team lacks operational experience
- Bad, because complex JOINs require application-level processing
- Good, because schema flexibility for rapidly changing product attributes
- Good, because horizontal scaling via sharding is native
- Bad, because eventual consistency unacceptable for financial transactions
- Bad, because team lacks operational experience
- Bad, because complex JOINs require application-level processing
CockroachDB
CockroachDB
- Good, because distributed SQL with horizontal scaling
- Good, because PostgreSQL-compatible wire protocol
- Bad, because higher operational complexity
- Bad, because smaller community, fewer managed service options
- Bad, because overkill for current scale (premature optimization)
- Good, because distributed SQL with horizontal scaling
- Good, because PostgreSQL-compatible wire protocol
- Bad, because higher operational complexity
- Bad, because smaller community, fewer managed service options
- Bad, because overkill for current scale (premature optimization)
More Information
More Information
- PostgreSQL vs MySQL comparison
- AWS RDS PostgreSQL
- Related: ADR-0005 (Read Replica Strategy)
---- PostgreSQL vs MySQL comparison
- AWS RDS PostgreSQL
- Related: ADR-0005 (Read Replica Strategy)
---📝 MADR Minimal Template
📝 MADR精简模板
For smaller decisions, use the minimal template:
markdown
---
status: accepted
date: 2024-01-15
---对于较小的决策,使用精简模板:
markdown
---
status: accepted
date: 2024-01-15
---Adopt Ruff for Python Linting
Adopt Ruff for Python Linting
Context
Context
We currently use flake8 + black + isort. Three tools with separate configs.
We currently use flake8 + black + isort. Three tools with separate configs.
Decision
Decision
Replace with Ruff — one tool, faster, compatible.
Replace with Ruff — one tool, faster, compatible.
Consequences
Consequences
- Good: Single config file, 10-100x faster
- Bad: Team needs to learn new rule codes
- Mitigation: Migration guide in docs/python-tooling.md
---- Good: Single config file, 10-100x faster
- Bad: Team needs to learn new rule codes
- Mitigation: Migration guide in docs/python-tooling.md
---📝 Y-Statement Template
📝 Y-Statement模板
For the fastest documentation (one sentence):
markdown
undefined用于快速记录(一句话):
markdown
undefinedY-Statement: API Gateway Selection
Y-Statement: API Gateway Selection
In the context of building a microservices architecture,
facing the need for centralized API management, authentication, and rate limiting,
we decided for Kong Gateway
and against AWS API Gateway and custom Nginx solution,
to achieve vendor independence, plugin extensibility, and team familiarity with Lua,
accepting that we need to manage Kong infrastructure ourselves.
---In the context of building a microservices architecture,
facing the need for centralized API management, authentication, and rate limiting,
we decided for Kong Gateway
and against AWS API Gateway and custom Nginx solution,
to achieve vendor independence, plugin extensibility, and team familiarity with Lua,
accepting that we need to manage Kong infrastructure ourselves.
---🏗️ ADR Directory Structure
🏗️ ADR目录结构
docs/
├── adr/
│ ├── README.md # Index and guidelines
│ ├── template.md # Your team's MADR template
│ ├── 0001-record-architecture-decisions.md
│ ├── 0002-use-postgresql.md
│ ├── 0003-caching-strategy.md
│ ├── 0004-microservices-vs-monolith.md
│ ├── 0005-read-replica-strategy.md
│ ├── 0006-graphql-api.md
│ ├── 0007-event-driven-architecture.md
│ ├── 0015-adopt-kubernetes.md
│ ├── 0016-container-orchestration.md # [SUPERSEDED by 0015]
│ └── 0020-deprecate-rest-v1.md # Supersedes implicit earlier decisiondocs/
├── adr/
│ ├── README.md # Index and guidelines
│ ├── template.md # Your team's MADR template
│ ├── 0001-record-architecture-decisions.md
│ ├── 0002-use-postgresql.md
│ ├── 0003-caching-strategy.md
│ ├── 0004-microservices-vs-monolith.md
│ ├── 0005-read-replica-strategy.md
│ ├── 0006-graphql-api.md
│ ├── 0007-event-driven-architecture.md
│ ├── 0015-adopt-kubernetes.md
│ ├── 0016-container-orchestration.md # [SUPERSEDED by 0015]
│ └── 0020-deprecate-rest-v1.md # Supersedes implicit earlier decisionADR Index (README.md)
ADR索引(README.md)
markdown
undefinedmarkdown
undefinedArchitecture Decision Records
Architecture Decision Records
Index
Index
| ADR | Title | Status | Date | Supersedes |
|---|---|---|---|---|
| 0001 | Record Architecture Decisions | Accepted | 2024-01-10 | — |
| 0002 | Use PostgreSQL as Primary Database | Accepted | 2024-01-15 | — |
| 0003 | Caching Strategy with Redis | Accepted | 2024-01-20 | — |
| 0004 | Start with Modular Monolith | Accepted | 2024-02-01 | — |
| 0005 | Read Replica Strategy | Accepted | 2024-02-15 | — |
| 0006 | GraphQL for Mobile API | Accepted | 2024-03-01 | — |
| 0007 | Event-Driven Architecture | Accepted | 2024-03-15 | — |
| 0015 | Adopt Kubernetes | Accepted | 2024-06-01 | 0016 |
| 0016 | Container Orchestration with Docker Swarm | Deprecated | 2024-01-30 | — |
| 0020 | Deprecate REST API v1 | Accepted | 2024-08-01 | — |
| ADR | Title | Status | Date | Supersedes |
|---|---|---|---|---|
| 0001 | Record Architecture Decisions | Accepted | 2024-01-10 | — |
| 0002 | Use PostgreSQL as Primary Database | Accepted | 2024-01-15 | — |
| 0003 | Caching Strategy with Redis | Accepted | 2024-01-20 | — |
| 0004 | Start with Modular Monolith | Accepted | 2024-02-01 | — |
| 0005 | Read Replica Strategy | Accepted | 2024-02-15 | — |
| 0006 | GraphQL for Mobile API | Accepted | 2024-03-01 | — |
| 0007 | Event-Driven Architecture | Accepted | 2024-03-15 | — |
| 0015 | Adopt Kubernetes | Accepted | 2024-06-01 | 0016 |
| 0016 | Container Orchestration with Docker Swarm | Deprecated | 2024-01-30 | — |
| 0020 | Deprecate REST API v1 | Accepted | 2024-08-01 | — |
Status Definitions
Status Definitions
- Proposed: Under discussion, seeking feedback
- Accepted: Decision made, being implemented
- Rejected: Considered but not adopted
- Deprecated: No longer relevant, but was accepted
- Superseded: Replaced by a newer ADR
- Proposed: Under discussion, seeking feedback
- Accepted: Decision made, being implemented
- Rejected: Considered but not adopted
- Deprecated: No longer relevant, but was accepted
- Superseded: Replaced by a newer ADR
Creating a New ADR
Creating a New ADR
- Copy to
template.mdNNNN-title-with-dashes.md - Fill in all sections
- Submit PR for team review
- Update this index after merge
---- Copy to
template.mdNNNN-title-with-dashes.md - Fill in all sections
- Submit PR for team review
- Update this index after merge
---🔄 ADR Lifecycle
🔄 ADR生命周期
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ PROPOSED │───▶│ ACCEPTED │───▶│DEPRECATED│ │ REJECTED │
└──────────┘ └────┬─────┘ └────┬─────┘ └──────────┘
│ │
│ ┌─────┘
│ ▼
│ ┌──────────┐
└───▶│SUPERSEDED│
│ by ADR-X │
└──────────┘┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ PROPOSED │───▶│ ACCEPTED │───▶│DEPRECATED│ │ REJECTED │
└──────────┘ └────┬─────┘ └────┬─────┘ └──────────┘
│ │
│ ┌─────┘
│ ▼
│ ┌──────────┐
└───▶│SUPERSEDED│
│ by ADR-X │
└──────────┘State Transitions
状态转换
| From | To | Trigger |
|---|---|---|
| Proposed | Accepted | Team consensus in PR review |
| Proposed | Rejected | Better alternative found |
| Accepted | Deprecated | Technology no longer used |
| Accepted | Superseded | New ADR replaces this decision |
| Deprecated | — | Historical reference only |
| 原状态 | 目标状态 | 触发条件 |
|---|---|---|
| Proposed | Accepted | PR评审中达成团队共识 |
| Proposed | Rejected | 找到更好的替代方案 |
| Accepted | Deprecated | 技术不再被使用 |
| Accepted | Superseded | 新ADR替代此决策 |
| Deprecated | — | 仅作为历史参考 |
🛠️ Automation with adr-tools
🛠️ 使用adr-tools自动化
bash
undefinedbash
undefinedInstall
Install
brew install adr-tools
brew install adr-tools
Initialize ADR directory
Initialize ADR directory
adr init docs/adr
adr init docs/adr
Create new ADR (auto-numbers)
Create new ADR (auto-numbers)
adr new "Use PostgreSQL as Primary Database"
adr new "Use PostgreSQL as Primary Database"
Creates: docs/adr/0002-use-postgresql-as-primary-database.md
Creates: docs/adr/0002-use-postgresql-as-primary-database.md
Supersede an ADR
Supersede an ADR
adr new -s 3 "Use Redis Cluster for Caching"
adr new -s 3 "Use Redis Cluster for Caching"
Creates new ADR that supersedes ADR-0003
Creates new ADR that supersedes ADR-0003
Link related ADRs
Link related ADRs
adr link 5 "Enables" 6 "Is enabled by"
adr link 5 "Enables" 6 "Is enabled by"
Generate table of contents
Generate table of contents
adr generate toc > docs/adr/README.md
---adr generate toc > docs/adr/README.md
---🎯 Decision Quality Checklist
🎯 决策质量检查清单
Before accepting an ADR, verify:
- Context is clear: Someone reading this in 2 years understands the problem
- Drivers are explicit: Criteria for evaluating options are stated
- Options are comprehensive: At least 3 alternatives considered (including "do nothing")
- Trade-offs are honest: Both good and bad consequences documented
- Decision is reversible: How hard to undo? (should be stated)
- Confirmation defined: How will we know this decision was correct?
- Stakeholders consulted: Decision-makers, consulted, informed listed
- Related ADRs linked: Dependencies and superseded decisions referenced
在接受ADR之前,验证以下内容:
- 背景清晰: 两年后阅读的人能理解当时的问题
- 驱动因素明确: 列出评估选项的标准
- 选项全面: 至少考虑3种替代方案(包括“不做任何改变”)
- 权衡诚实: 同时记录正面和负面后果
- 决策可逆: 说明撤销决策的难度
- 确认方式明确: 如何验证此决策是否正确
- 咨询相关方: 列出决策者、咨询对象和告知对象
- 关联ADR链接: 引用依赖关系和被替代的决策
🚫 ADR Anti-Patterns
🚫 ADR反模式
| Anti-Pattern | Symptom | Fix |
|---|---|---|
| Decision Without Context | "We chose X" with no explanation | Always include "why this problem matters" |
| One Option Only | Only the chosen option documented | Document all considered options with pros/cons |
| No Consequences | Only positive outcomes listed | Be honest about negative consequences |
| Perpetual Proposed | ADR stays "proposed" for months | Set decision deadline (e.g., 2 weeks) |
| Editing Accepted ADRs | Changing ADR-0002 after acceptance | Create ADR-0020 that supersedes it |
| ADR for Everything | ADR for linter rule changes | Use minimal template or skip for trivial decisions |
| Missing Links | Related decisions not connected | Use |
| 反模式 | 症状 | 修复方案 |
|---|---|---|
| 无背景的决策 | 只写“我们选择了X”却没有解释 | 始终包含“此问题为何重要”的说明 |
| 仅记录单一选项 | 只记录被选中的选项 | 记录所有考虑过的选项及其优缺点 |
| 未记录后果 | 只列出正面结果 | 诚实记录负面后果 |
| 长期处于提议状态 | ADR数月保持“proposed”状态 | 设置决策截止日期(如2周) |
| 修改已接受的ADR | 接受后修改ADR-0002 | 创建ADR-0020替代原ADR |
| 所有决策都写ADR | 为代码检查规则变更编写ADR | 使用精简模板或跳过琐碎决策 |
| 缺少关联链接 | 相关决策未关联 | 使用 |
🔗 Integration with Other Skills
🔗 与其他技能的集成
| Skill | Integration |
|---|---|
| ADRs document "why" behind C4 L2 container choices |
| ADRs capture subdomain classification decisions |
| ADR = technical implementation of WHY statement |
| ADRs track architectural dimension decisions |
| 技能 | 集成方式 |
|---|---|
| ADR记录C4 L2容器选择背后的“原因” |
| ADR捕获子域分类决策 |
| ADR是WHY声明的技术实现 |
| ADR跟踪架构维度决策 |
📚 References
📚 参考资料
- MADR 4.0.0 — Official specification
- ADR GitHub Organization — Templates and tools
- Documenting Architecture Decisions — Michael Nygard (original)
- Y-Statements — Sustainable Architectural Decisions
- adr-tools — Command-line tools
- MADR 4.0.0 — 官方规范
- ADR GitHub Organization — 模板和工具
- Documenting Architecture Decisions — Michael Nygard(原创)
- Y-Statements — 可持续架构决策
- adr-tools — 命令行工具