Skills › Software Development › Code quality & review
architecture-decision-records
Write and maintain Architecture Decision Records (ADRs) following best practices for technical decision documentation. Use when documenting significant technical decisions, reviewing past architectural choices, or establishing decision processes.
Tools: adr-tools
The full skill
—
name: architecture-decision-records
description: Write and maintain Architecture Decision Records (ADRs) following best practices for technical decision documentation. Use when documenting significant technical decisions, reviewing past architectural choices, or establishing decision processes.
—
# Architecture Decision Records
Comprehensive patterns for creating, maintaining, and managing Architecture Decision Records (ADRs) that capture the context and rationale behind significant technical decisions.
## When to Use This Skill
– Making significant architectural decisions
– Documenting technology choices
– Recording design trade-offs
– Onboarding new team members
– Reviewing historical decisions
– Establishing decision-making processes
## Core Concepts
### 1. What is an ADR?
An Architecture Decision Record captures:
– **Context**: Why we needed to make a decision
– **Decision**: What we decided
– **Consequences**: What happens as a result
### 2. When to Write an ADR
| Write ADR | Skip ADR |
|———–|———-|
| New framework adoption | Minor version upgrades |
| Database technology choice | Bug fixes |
| API design patterns | Implementation details |
| Security architecture | Routine maintenance |
| Integration patterns | Configuration changes |
### 3. ADR Lifecycle
“`
Proposed â Accepted â Deprecated â Superseded
â
Rejected
“`
## Templates
### Template 1: Standard ADR (MADR Format)
“`markdown
# ADR-0001: Use PostgreSQL as Primary Database
## Status
Accepted
## Context
We need to select a primary database for our new e-commerce platform. The system
will handle:
– ~10,000 concurrent users
– Complex product catalog with hierarchical categories
– Transaction processing for orders and payments
– Full-text search for products
– Geospatial queries for store locator
The team has experience with MySQL, PostgreSQL, and MongoDB. We need ACID
compliance for financial transactions.
## Decision Drivers
* **Must have ACID compliance** for payment processing
* **Must support complex queries** for reporting
* **Should support full-text search** to reduce infrastructure complexity
* **Should have good JSON support** for flexible product attributes
* **Team familiarity** reduces onboarding time
## Considered Options
### Option 1: PostgreSQL
– **Pros**: ACID compliant, excellent JSON support (JSONB), built-in full-text
search, PostGIS for geospatial, team has experience
– **Cons**: Slightly more complex replication setup than MySQL
### Option 2: MySQL
– **Pros**: Very familiar to team, simple replication, large community
– **Cons**: Weaker JSON support, no built-in full-text search (need
Elasticsearch), no geospatial without extensions
### Option 3: MongoDB
– **Pros**: Flexible schema, native JSON, horizontal scaling
– **Cons**: No ACID for multi-document transactions (at decision time),
team has limited experience, requires schema design discipline
## Decision
We will use **PostgreSQL 15** as our primary database.
## Rationale
PostgreSQL provides the best balance of:
1. **ACID compliance** essential for e-commerce transactions
2. **Built-in capabilities** (full-text search, JSONB, PostGIS) reduce
infrastructure complexity
3. **Team familiarity** with SQL databases reduces learning curve
4. **Mature ecosystem** with excellent tooling and community support
The slight complexity in replication is outweighed by the reduction in
additional services (no separate Elasticsearch needed).
## Consequences
### Positive
– Single database handles transactions, search, and geospatial queries
– Reduced operational complexity (fewer services to manage)
– Strong consistency guarantees for financial data
– Team can leverage existing SQL expertise
### Negative
– Need to learn PostgreSQL-specific features (JSONB, full-text search syntax)
– Vertical scaling limits may require read replicas sooner
– Some team members need PostgreSQL-specific training
### Risks
– Full-text search may not scale as well as dedicated search engines
– Mitigation: Design for potential Elasticsearch addition if needed
## Implementation Notes
– Use JSONB for flexible product attributes
– Implement connection pooling with PgBouncer
– Set up streaming replication for read replicas
– Use pg_trgm extension for fuzzy search
## Related Decisions
– ADR-0002: Caching Strategy (Redis) – complements database choice
– ADR-0005: Search Architecture – may supersede if Elasticsearch needed
## References
– [PostgreSQL JSON Documentation](https://www.postgresql.org/docs/current/datatype-json.html)
– [PostgreSQL Full Text Search](https://www.postgresql.org/docs/current/textsearch.html)
– Internal: Performance benchmarks in `/docs/benchmarks/database-comparison.md`
“`
### Template 2: Lightweight ADR
“`markdown
# ADR-0012: Adopt TypeScript for Frontend Development
**Status**: Accepted
**Date**: 2024-01-15
**Deciders**: @alice, @bob, @charlie
## Context
Our React codebase has grown to 50+ components with increasing bug reports
related to prop type mismatches and undefined errors. PropTypes provide
runtime-only checking.
## Decision
Adopt TypeScript for all new frontend code. Migrate existing code incrementally.
## Consequences
**Good**: Catch type errors at compile time, better IDE support, self-documenting
code.
**Bad**: Learning curve for team, initial slowdown, build complexity increase.
**Mitigations**: TypeScript training sessions, allow gradual adoption with
`allowJs: true`.
“`
### Template 3: Y-Statement Format
“`markdown
# ADR-0015: 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**.
“`
### Template 4: ADR for Deprecation
“`markdown
# ADR-0020: Deprecate MongoDB in Favor of PostgreSQL
## Status
Accepted (Supersedes ADR-0003)
## Context
ADR-0003 (2021) chose MongoDB for user profile storage due to schema flexibility
needs. Since then:
– MongoDB's multi-document transactions remain problematic for our use case
– Our schema has stabilized and rarely changes
– We now have PostgreSQL expertise from other services
– Maintaining two databases increases operational burden
## Decision
Deprecate MongoDB and migrate user profiles to PostgreSQL.
## Migration Plan
1. **Phase 1** (Week 1-2): Create PostgreSQL schema, dual-write enabled
2. **Phase 2** (Week 3-4): Backfill historical data, validate consistency
3. **Phase 3** (Week 5): Switch reads to PostgreSQL, monitor
4. **Phase 4** (Week 6): Remove MongoDB writes, decommission
## Consequences
### Positive
– Single database technology reduces operational complexity
– ACID transactions for user data
– Team can focus PostgreSQL expertise
### Negative
– Migration effort (~4 weeks)
– Risk of data issues during migration
– Lose some schema flexibility
## Lessons Learned
Document from ADR-0003 experience:
– Schema flexibility benefits were overestimated
– Operational cost of multiple databases was underestimated
– Consider long-term maintenance in technology decisions
“`
### Template 5: Request for Comments (RFC) Style
“`markdown
# RFC-0025: Adopt Event Sourcing for Order Management
## Summary
Propose adopting event sourcing pattern for the order management domain to
improve auditability, enable temporal queries, and support business analytics.
## Motivation
Current challenges:
1. Audit requirements need complete order history
2. "What was the order state at time X?" queries are impossible
3. Analytics team needs event stream for real-time dashboards
4. Order state reconstruction for customer support is manual
## Detailed Design
### Event Store
“`
OrderCreated { orderId, customerId, items[], timestamp }
OrderItemAdded { orderId, item, timestamp }
OrderItemRemoved { orderId, itemId, timestamp }
PaymentReceived { orderId, amount, paymentId, timestamp }
OrderShipped { orderId, trackingNumber, timestamp }
“`
### Projections
– **CurrentOrderState**: Materialized view for queries
– **OrderHistory**: Complete timeline for audit
– **DailyOrderMetrics**: Analytics aggregation
### Technology
– Event Store: EventStoreDB (purpose-built, handles projections)
– Alternative considered: Kafka + custom projection service
## Drawbacks
– Learning curve for team
– Increased complexity vs. CRUD
– Need to design events carefully (immutable once stored)
– Storage growth (events never deleted)
## Alternatives
1. **Audit tables**: Simpler but doesn't enable temporal queries
2. **CDC from existing DB**: Complex, doesn't change data model
3. **Hybrid**: Event source only for order state changes
## Unresolved Questions
– [ ] Event schema versioning strategy
– [ ] Retention policy for events
– [ ] Snapshot frequency for performance
## Implementation Plan
1. Prototype with single order type (2 weeks)
2. Team training on event sourcing (1 week)
3. Full implementation and migration (4 weeks)
4. Monitoring and optimization (ongoing)
## References
– [Event Sourcing by Martin Fowler](https://martinfowler.com/eaaDev/EventSourcing.html)
– [EventStoreDB Documentation](https://www.eventstore.com/docs)
“`
## ADR Management
### Directory Structure
“`
docs/
âââ adr/
â âââ README.md # Index and guidelines
â âââ template.md # Team's ADR template
â âââ 0001-use-postgresql.md
â âââ 0002-caching-strategy.md
â âââ 0003-mongodb-user-profiles.md # [DEPRECATED]
â âââ 0020-deprecate-mongodb.md # Supersedes 0003
“`
### ADR Index (README.md)
“`markdown
# Architecture Decision Records
This directory contains Architecture Decision Records (ADRs) for [Project Name].
## Index
| ADR | Title | Status | Date |
|—–|——-|——–|——|
| [0001](0001-use-postgresql.md) | Use PostgreSQL as Primary Database | Accepted | 2024-01-10 |
| [0002](0002-caching-strategy.md) | Caching Strategy with Redis | Accepted | 2024-01-12 |
| [0003](0003-mongodb-user-profiles.md) | MongoDB for User Profiles | Deprecated | 2023-06-15 |
| [0020](0020-deprecate-mongodb.md) | Deprecate MongoDB | Accepted | 2024-01-15 |
## Creating a New ADR
1. Copy `template.md` to `NNNN-title-with-dashes.md`
2. Fill in the template
3. Submit PR for review
4. Update this index after approval
## ADR Status
– **Proposed**: Under discussion
– **Accepted**: Decision made, implementing
– **Deprecated**: No longer relevant
– **Superseded**: Replaced by another ADR
– **Rejected**: Considered but not adopted
“`
### Automation (adr-tools)
“`bash
# Install adr-tools
brew install adr-tools
# Initialize ADR directory
adr init docs/adr
# Create new ADR
adr new "Use PostgreSQL as Primary Database"
# Supersede an ADR
adr new -s 3 "Deprecate MongoDB in Favor of PostgreSQL"
# Generate table of contents
adr generate toc > docs/adr/README.md
# Link related ADRs
adr link 2 "Complements" 1 "Is complemented by"
“`
## Review Process
“`markdown
## ADR Review Checklist
### Before Submission
– [ ] Context clearly explains the problem
– [ ] All viable options considered
– [ ] Pros/cons balanced and honest
– [ ] Consequences (positive and negative) documented
– [ ] Related ADRs linked
### During Review
– [ ] At least 2 senior engineers reviewed
– [ ] Affected teams consulted
– [ ] Security implications considered
– [ ] Cost implications documented
– [ ] Reversibility assessed
### After Acceptance
– [ ] ADR index updated
– [ ] Team notified
– [ ] Implementation tickets created
– [ ] Related documentation updated
“`
## Best Practices
### Do's
– **Write ADRs early** – Before implementation starts
– **Keep them short** – 1-2 pages maximum
– **Be honest about trade-offs** – Include real cons
– **Link related decisions** – Build decision graph
– **Update status** – Deprecate when superseded
### Don'ts
– **Don't change accepted ADRs** – Write new ones to supersede
– **Don't skip context** – Future readers need background
– **Don't hide failures** – Rejected decisions are valuable
– **Don't be vague** – Specific decisions, specific consequences
– **Don't forget implementation** – ADR without action is waste
## Resources
– [Documenting Architecture Decisions (Michael Nygard)](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions)
– [MADR Template](https://adr.github.io/madr/)
– [ADR GitHub Organization](https://adr.github.io/)
– [adr-tools](https://github.com/npryce/adr-tools)