7 min read • Guide 157 of 877
Documenting Architectural Decisions
Technical decisions made today will be questioned tomorrow by new team members, auditors, or your future self. Architecture Decision Records (ADRs) capture not just what was decided, but why, what alternatives were considered, and what consequences to expect.
ADR Benefits
| Without ADRs | With ADRs |
|---|---|
| "Why did we use X?" | Documented reasoning |
| Revisiting old debates | Decision history |
| Inconsistent approaches | Established patterns |
| Lost context | Preserved knowledge |
| New hire confusion | Clear onboarding |
ADR Format
Standard Template
ARCHITECTURE DECISION RECORD TEMPLATE
═════════════════════════════════════
# ADR-[NUMBER]: [TITLE]
## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXX]
## Date
[YYYY-MM-DD when decided]
## Context
[What is the situation? What problem are we trying to solve?
What constraints do we have? What forces are at play?]
## Decision
[What is the decision we're making? Be clear and specific.]
## Alternatives Considered
### Alternative 1: [Name]
- Pros: [list]
- Cons: [list]
- Why not chosen: [reason]
### Alternative 2: [Name]
- Pros: [list]
- Cons: [list]
- Why not chosen: [reason]
## Consequences
### Positive
- [benefit 1]
- [benefit 2]
### Negative
- [drawback 1]
- [drawback 2]
### Risks
- [risk and mitigation]
## Related Decisions
- [ADR-XXX: Related decision]
## References
- [Links to relevant documentation, RFCs, etc.]
Real Example
# ADR-005: Use PostgreSQL for Primary Database
## Status
Accepted
## Date
2024-01-15
## Context
We need to select a primary database for our SaaS application.
Requirements:
- Strong consistency for financial transactions
- Complex queries for analytics
- JSON support for flexible schemas
- Proven reliability at scale
- Team familiarity
- Reasonable operational complexity
Current team has experience with MySQL and PostgreSQL.
Expected load: 10K transactions/day initially, scaling to 1M+.
## Decision
Use PostgreSQL 16 as our primary database, deployed on
AWS RDS with Multi-AZ configuration.
## Alternatives Considered
### Alternative 1: MySQL
- Pros: Team familiarity, simple setup, good performance
- Cons: Weaker JSON support, fewer advanced features
- Why not chosen: JSON support critical for our schema needs
### Alternative 2: MongoDB
- Pros: Flexible schema, good for documents
- Cons: Eventual consistency concerns for transactions
- Why not chosen: Need strong consistency for financial data
### Alternative 3: CockroachDB
- Pros: Distributed by design, PostgreSQL compatible
- Cons: Complexity overkill for current scale, cost
- Why not chosen: Premature optimization for our scale
## Consequences
### Positive
- Strong ecosystem with extensive tooling
- JSONB support for flexible portions of schema
- Excellent query planner for complex analytics
- Team can leverage existing PostgreSQL knowledge
- RDS simplifies operations
### Negative
- Horizontal scaling will require read replicas or sharding
- Not ideal for time-series data (may need separate solution)
- RDS costs higher than self-managed
### Risks
- Scale ceiling: Mitigate with read replicas, caching layer
- Vendor lock-in to RDS: Acceptable trade-off for reduced ops
## Related Decisions
- ADR-012: TimescaleDB for metrics data
- ADR-003: Redis for caching layer
## References
- PostgreSQL docs: https://postgresql.org/docs/16/
- AWS RDS pricing analysis: [internal doc]
When to Create ADRs
Decision Criteria
CREATE AN ADR WHEN:
═══════════════════
HIGH IMPACT:
├── Affects multiple services/components
├── Difficult or expensive to reverse
├── Significant development effort
├── Team had substantial debate
└── External stakeholder interest
EXAMPLES:
├── Choosing a database
├── Selecting a framework
├── Defining API architecture
├── Choosing authentication approach
├── Deciding deployment strategy
├── Establishing coding standards
├── Picking cloud provider
└── Defining data retention policy
DON'T NEED ADR:
├── Choosing variable names
├── Minor library selection
├── Bug fix approaches
├── UI component styling
└── Easily reversible choices
ADR Workflow
ADR CREATION WORKFLOW
═════════════════════
STEP 1: Identify Decision
├── Significant technical choice ahead
├── Team has different opinions
├── Will affect future development
└── Worth documenting
STEP 2: Draft ADR
├── Author creates draft
├── Includes context and constraints
├── Lists alternatives considered
├── Proposes decision
└── Status: "Proposed"
STEP 3: Review
├── Share with affected teams
├── Collect feedback (comments/PR)
├── Technical discussion
├── May revise based on input
└── Time-box: 1 week typical
STEP 4: Decide
├── Team meeting or async vote
├── Make final decision
├── Update ADR with decision
└── Status: "Accepted"
STEP 5: Communicate
├── Announce decision
├── Link from relevant code/docs
├── Reference in implementation PRs
└── Add to onboarding materials
Organizing ADRs
Folder Structure
ADR ORGANIZATION
════════════════
IN REPOSITORY:
─────────────────────────────────────
project/
├── docs/
│ └── adr/
│ ├── README.md (index)
│ ├── 0001-record-architecture-decisions.md
│ ├── 0002-use-typescript.md
│ ├── 0003-graphql-api-design.md
│ ├── 0004-microservices-vs-monolith.md
│ └── 0005-postgresql-database.md
├── src/
└── ...
README.md INDEX:
─────────────────────────────────────
# Architecture Decision Records
| # | Title | Status | Date |
|---|-------|--------|------|
| 1 | Record architecture decisions | Accepted | 2024-01-01 |
| 2 | Use TypeScript | Accepted | 2024-01-05 |
| 3 | GraphQL API design | Accepted | 2024-01-10 |
| 4 | Microservices vs monolith | Accepted | 2024-01-15 |
| 5 | PostgreSQL database | Accepted | 2024-01-15 |
NUMBERING:
├── Sequential: 0001, 0002, 0003...
├── Never reuse numbers
├── Deprecated ADRs keep numbers
└── Superseded points to replacement
In GitScrum NoteVault
ADRS IN NOTEVAULT
═════════════════
ORGANIZATION:
├── Create "Architecture Decisions" space
├── Tag ADRs with #adr
├── Link to related projects
├── Link to implementation tasks
└── Search across all ADRs
LINKING:
├── ADR → Task that implements it
├── Task → ADR that explains why
├── Project → Key ADRs
└── Bidirectional references
TEMPLATES:
├── Save ADR template in NoteVault
├── Create new ADR from template
├── Consistent structure
└── Required fields enforced
Maintaining ADRs
Lifecycle Management
ADR LIFECYCLE
═════════════
PROPOSED:
├── Draft stage
├── Open for discussion
├── Not yet decided
└── May be rejected
ACCEPTED:
├── Decision made
├── Implementation can proceed
├── Reference in code
└── Most common final state
DEPRECATED:
├── No longer relevant
├── Technology changed
├── Business changed
├── Keep for history
└── Note why deprecated
SUPERSEDED:
├── Replaced by newer ADR
├── Link to replacement
├── Original still valuable for history
└── "Superseded by ADR-XXX"
EXAMPLE:
# ADR-003: Use REST API
## Status
Superseded by ADR-015 (GraphQL migration)
[Original content preserved for history]
Best Practices
For ADRs
- Write at decision time — Context fresh
- Keep them short — Focused on decision
- Store with code — Easy to find
- Never delete — History matters
- Reference in code — Link implementation
Anti-Patterns
ADR MISTAKES:
✗ Writing months after decision
✗ Too long (multiple pages)
✗ Storing separately from code
✗ Deleting deprecated ADRs
✗ No alternatives documented
✗ No consequences listed
✗ No review process
✗ Never referenced again