A version-controlled log of short records documenting significant architectural decisions, their context, the alternatives considered, and the consequences accepted.
Why did we build it this way, and what trade-offs did we accept?
An Architecture DecisionDecisionStrategyA recorded decision with context, rationale, and consequencesView reference → Record (ADR) log is a version-controlled collection of short text files, one per significant architectural choice, that records what was decided, why, what alternatives were weighed, and what the team expects to happen as a result. The format turns fleeting verbal agreements into a durable, searchable audit trail that survives staff changes, reorgs, and the passage of time.
The format was popularised by Michael Nygard in a November 2011 blog post titled "Documenting Architecture Decisions", published on the Cognitect blog. Nygard was reacting to a common breakdown in long-running projects: decisions that shaped the codebase for years had never been written down, so new engineers spent weeks reverse-engineering the "why" behind things they could plainly see. His proposed fix was deliberately minimal. Each record fits on a single screen, uses a fixed five-section template (Title, Context, Decision, Status, Consequences), and lives in the same repository as the code it describes. That adjacency matters: the record travels with the code through branches, pull requests, and deploymentsDeploymentEngineeringA deployment eventView reference →.
The format spread steadily through the software-architecture community during the 2010s. The open-source MADR project (Markdown Architectural Decision Records) at adr.github.io introduced a slightly richer template with explicit "Options Considered" and "Pros and Cons" sub-sections. Martin Fowler wrote a widely-read bliki entry endorsing the practice. Today most ADR guidance treats the Nygard five-section shape as the minimum and MADR as the fuller variantVariantGrowthA variant in an A/B testView reference →. Large engineering organisations including GitHub, AWS, and Spotify have published their own template variants while preserving the core idea.
The log lives in a directory inside the repository, typically docs/decisions/ or docs/adr/. Each file is numbered sequentially and given a short, noun-phrase title: 0012-use-postgres-as-primary-store.md, for example.
A record in Nygard's format contains:
proposed, accepted, deprecated, or superseded. The status field makes the log a living artefact, not just an archiveA worked example. A two-person startup running a Ruby on Rails app decides it needsNeedUserA user need, pain, desire, or constraintView reference → a jobJobUserJob To Be Done: what the user is trying to accomplishView reference → queue. The context section notes that the team already runs Postgres, has no Redis budget, and needs fewer than 5,000 jobs per day. The decision is to use GoodJob (a Postgres-backed job queue gem). The consequences note that this avoids a new infrastructure dependencyDependencyTeam & OrganisationA cross-team or system dependencyView reference →, accepts a ceiling on throughput, and means the job queue shares Postgres connection pool headroom with the web tier. Six months later, when throughput triples and the team adopts Redis, a second ADR is written to supersede the first. The new record links back to the old one; the old one has its status updated to superseded by ADR-0031.
The key discipline is writing ADRs in the moment. Records written retrospectively lose the contextual detail that makes them valuable. A good trigger is the pull-request review: if a PR introduces an architectural choice that would prompt a "why did you do it this way?" question, an ADR belongs alongside it.
ADR logs suit any project where architectural choices compound over time and where team membership changes. They are especially useful in services that will outlive their founding engineers, in open-source projects with many contributors, and in regulated environments where auditors need evidenceEvidenceValidationData supporting or refuting a hypothesisView reference → of technical governance.
The format earns its keep when the team has more than two or three engineers, when the codebase will run for more than a year, or when technical choices carry real trade-offs worth preserving for later review.
It is less useful when the team is a single developer building a short-lived prototypePrototypeExperience DesignAn interactive mockup for testingView reference →, or when every architectural choice is driven by a single external mandate with no genuine options. Writing ADRs in those situations is ceremony without return.
The common failure modes: treating every minor library choice as ADR-worthy (the log bloats and loses signal), writing records so long that nobody reads them (break the Nygard discipline), and writing them only for decisions that turned out well (the records that document accepted risks are the most valuable ones). Equally damaging is writing records but never updating their status when they are superseded. A stale log actively misleads new team members.
The ADR log is a table framework in the engineering category. Each row in the log is a distinct entity, and the Unified Product Graph models the four core sections of a Nygard-format record across four entity types:
decisionDecisionStrategyA recorded decision with context, rationale, and consequencesView reference → entity, capturing the choice made and the date it was accepted.bounded_contextBounded ContextEngineeringA DDD bounded context defining a service boundaryView reference → entity, the bounded system or service area the decision governs.solutionSolutionDiscoveryA proposed approach to address an opportunityView reference → entity, one per alternative the team evaluated, with the rejected options preserved alongside the accepted one.outcomeOutcomeStrategyA desired business or user outcomeView reference → entities, the expected effects the team documented at the time of the decision.Representing options and consequences as first-class entities means a rejected SolutionDiscoveryA proposed approach to address an opportunityView reference → can later be linked to a new solutionDecisionStrategyA recorded decision with context, rationale, and consequencesView reference → when the team revisits it, and an decisionOutcomeStrategyA desired business or user outcomeView reference → that failed to materialise can be flagged. The log stops being a static document archive and becomes a connected layer of the product graph, where decisions reference the services they shaped and the hypothesesHypothesisValidationA testable belief about a solutionView reference → they encoded.outcome