architecture-decision-records

编写和维护架构决策记录(ADR),遵循技术决策文档的最佳实践。适用于记录重大技术决策、审查过往架构选择或建立决策流程的场景。

查看详情
name:architecture-decision-recordsdescription: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.

Use this skill when

  • Making significant architectural decisions

  • Documenting technology choices

  • Recording design trade-offs

  • Onboarding new team members

  • Reviewing historical decisions

  • Establishing decision-making processes
  • Do not use this skill when

  • You only need to document small implementation details

  • The change is a minor patch or routine maintenance

  • There is no architectural decision to capture
  • Instructions

  • Capture the decision context, constraints, and drivers.

  • Document considered options with tradeoffs.

  • Record the decision, rationale, and consequences.

  • Link related ADRs and update status over time.
  • 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 ADRSkip ADR
    New framework adoptionMinor version upgrades
    Database technology choiceBug fixes
    API design patternsImplementation details
    Security architectureRoutine maintenance
    Integration patternsConfiguration changes

    3. ADR Lifecycle

    Proposed → Accepted → Deprecated → Superseded

    Rejected

    Templates

    Template 1: Standard ADR (MADR Format)

    # 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:

  • ACID compliance essential for e-commerce transactions

  • Built-in capabilities (full-text search, JSONB, PostGIS) reduce

  • infrastructure complexity
  • Team familiarity with SQL databases reduces learning curve

  • 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

  • PostgreSQL Full Text Search

  • Internal: Performance benchmarks in /docs/benchmarks/database-comparison.md
  • Template 2: Lightweight ADR

    # 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

    # 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

    # 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

  • Phase 1 (Week 1-2): Create PostgreSQL schema, dual-write enabled

  • Phase 2 (Week 3-4): Backfill historical data, validate consistency

  • Phase 3 (Week 5): Switch reads to PostgreSQL, monitor

  • 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

    # 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:

  • Audit requirements need complete order history

  • "What was the order state at time X?" queries are impossible

  • Analytics team needs event stream for real-time dashboards

  • 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

  • Audit tables: Simpler but doesn't enable temporal queries

  • CDC from existing DB: Complex, doesn't change data model

  • Hybrid: Event source only for order state changes
  • Unresolved Questions

  • [ ] Event schema versioning strategy

  • [ ] Retention policy for events

  • [ ] Snapshot frequency for performance
  • Implementation Plan

  • Prototype with single order type (2 weeks)

  • Team training on event sourcing (1 week)

  • Full implementation and migration (4 weeks)

  • Monitoring and optimization (ongoing)
  • References

  • Event Sourcing by Martin Fowler

  • EventStoreDB Documentation
  • 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)

    # Architecture Decision Records

    This directory contains Architecture Decision Records (ADRs) for [Project Name].

    Index

    <div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">ADR</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Title</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Status</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Date</th></tr></thead><tbody class="divide-y divide-border"><tr><td class="px-4 py-2 text-sm text-foreground"><a href="0001-use-postgresql.md" class="text-primary hover:underline" target="_blank" rel="noopener noreferrer">0001</a></td><td class="px-4 py-2 text-sm text-foreground">Use PostgreSQL as Primary Database</td><td class="px-4 py-2 text-sm text-foreground">Accepted</td><td class="px-4 py-2 text-sm text-foreground">2024-01-10</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><a href="0002-caching-strategy.md" class="text-primary hover:underline" target="_blank" rel="noopener noreferrer">0002</a></td><td class="px-4 py-2 text-sm text-foreground">Caching Strategy with Redis</td><td class="px-4 py-2 text-sm text-foreground">Accepted</td><td class="px-4 py-2 text-sm text-foreground">2024-01-12</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><a href="0003-mongodb-user-profiles.md" class="text-primary hover:underline" target="_blank" rel="noopener noreferrer">0003</a></td><td class="px-4 py-2 text-sm text-foreground">MongoDB for User Profiles</td><td class="px-4 py-2 text-sm text-foreground">Deprecated</td><td class="px-4 py-2 text-sm text-foreground">2023-06-15</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><a href="0020-deprecate-mongodb.md" class="text-primary hover:underline" target="_blank" rel="noopener noreferrer">0020</a></td><td class="px-4 py-2 text-sm text-foreground">Deprecate MongoDB</td><td class="px-4 py-2 text-sm text-foreground">Accepted</td><td class="px-4 py-2 text-sm text-foreground">2024-01-15</td></tr></tbody></table></div>

    Creating a New ADR

  • Copy template.md to NNNN-title-with-dashes.md

  • Fill in the template

  • Submit PR for review

  • 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)

    # 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

    ## 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)

  • MADR Template

  • ADR GitHub Organization

  • adr-tools