What is an ADR and Why is it Used?
An Architecture Decision Record (ADR) is a text file that documents the context, rationale, and consequences of significant architectural decisions made by a team. Recording why decisions were made and which alternatives were evaluated allows new team members to quickly look back at the history and understand the evolution of the current architecture.
Official sources (GitHub ADR, AWS Prescriptive Guidance) emphasize that an ADR consists of three core components: "decision, context, and consequences." For example, when performance issues arise after a database selection, the alternatives and risk analyses recorded in the ADR make it easier to quickly isolate the problem and temporarily roll back to a previous solution.
The ADR Process and Template
The ADR process is typically carried out through the following steps:
- Defining the decision need – The emergence of an architectural problem and the search for a solution.
- Gathering alternatives – The advantages, disadvantages, cost, and risk analyses of each alternative.
-
Documenting the decision – Filling out the
adr-template.mdtemplate. - Review and approval – Obtaining team approval via a Pull Request (PR).
- Adding to version control – Storing the ADR file within the repository.
The code block below demonstrates the steps to create a new ADR and add it to Git:
# 1. Copy the ADR template
cp adr-template.md docs/adr/2026-08-28-data-layer-choice.md
# 2. Edit the file (example line)
sed -i 's/{{title}}/Data Layer Choice/' docs/adr/2026-08-28-data-layer-choice.md
# 3. Stage the change
git add docs/adr/2026-08-28-data-layer-choice.md
# 4. Create a commit
git commit -m "Add ADR: Data layer choice"
# Output (a real git commit example)
# [main 4f2c9a1] Add ADR: Data layer choice
# 1 file changed, 12 insertions(+), 0 deletions(-)
# create mode 100644 docs/adr/2026-08-28-data-layer-choice.md
These steps clearly show the source of the decision and who approved it.
Integrating ADR with CI/CD
Integrating ADR documents into the CI/CD process automatically checks the consistency of decisions. For example, running an adr-lint tool within a pipeline can enforce the following rules:
- The ADR file's
statusfield must contain one of the values: "Accepted", "Superseded", or "Deprecated". These states are part of the ADR lifecycle. - The
datefield must comply with the ISO-8601 format.
The following GitHub Actions example performs an ADR lint check on every PR:
name: ADR Format Validation
on:
pull_request:
paths:
- 'docs/adr/**/*.md'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate ADR format
run: |
# Basic format validation of ADR files (e.g., presence of title, date, status field)
find docs/adr -name "*.md" -exec grep -L "## Decision" {} \; || exit 1
If an ADR file does not contain the mandatory components (such as the '## Decision' heading), the pipeline fails, and the team cannot merge without fixing the error. This ensures consistency in decision documentation.
ADR Management and Review
Over time, ADRs can transition to "superseded" (replaced by a new decision) or "deprecated" (no longer valid) status. An index.md file can be used to track these statuses. The file lists the current status of each ADR:
| ADR | Title | Status | Date |
|-----|----------------------------|------------|------------|
| 0001| Data Layer Choice | Accepted | 2026-08-28 |
| 0002| Logging Solution | Superseded | 2025-11-12 |
The following steps are followed during the review process:
- Change request – The "Status" field under an existing ADR is updated to "Superseded" and a new ADR is created.
- Rollback plan – If the new decision needs to be reverted, the previous architecture is redeployed by referencing the prior ADR.
This process clarifies the evolution of decisions and retrospective accountability.
Example Scenario: Choosing a New Data Layer
Scenario: A microservices platform wants to add a NoSQL data layer instead of PostgreSQL due to high read traffic.
Step 1 – Gathering Alternatives
| Alternative | Advantage | Disadvantage |
|---|---|---|
| MongoDB | Low latency, flexible schema | Limited ACID support |
| Cassandra | Horizontal scalability | Operational complexity |
| Redis (persist) | Extremely fast reads | Limited data persistence |
Step 2 – Risk Analysis
- Data consistency – If ACID requirements are high, MongoDB is preferred; otherwise, eventual consistency is acceptable.
- Operational cost – Managing Cassandra nodes introduces additional overhead for the operations team.
Step 3 – Decision and Documentation
Decision: MongoDB is selected.
The following sections are added to the ADR file:
## Decision
Use MongoDB as the primary read-optimized data store.
## Consequences
- Application code will need to handle BSON serialization.
- Backup strategy will rely on MongoDB's built‑in point‑in‑time recovery.
Step 4 – Validation
Post-deployment, data is inserted using a simple mongo CLI command, and the read time is measured:
$ mongo --eval 'db.test.insertOne({key:"value"})'
$ time mongo --eval 'db.test.findOne({key:"value"})'
real 0m0.012s
This output shows that the read time is at the millisecond level; the performance expectation has been met.
Step 5 – Rollback
If MongoDB does not provide the expected consistency, we comment out the MongoDB service in docker-compose.yml and reactivate the PostgreSQL service:
services:
# mongo:
# image: mongo:6.0
# restart: always
postgres:
image: postgres:15
restart: always
This change is applied with the docker compose up -d command in the same CI pipeline, and the system rolls back to the previous data layer.
Common Pitfalls and Solutions
-
Forgetting ADR files – This happens when CI lint rules are missing. Solution: Add a pipeline that mandates checks for all
docs/adr/**/*.mdfiles using apathsfilter. - Over-detailing decisions – Unnecessary technical details make the document unreadable. Solution: Keep the "Rationale" section limited to 2-3 paragraphs and redirect technical details to relevant code comments.
-
Outdated ADRs – If the
index.mdfile is not updated automatically, decisions become inconsistent. Solution: Regenerate the index file on every PR using a tool likeadr-index-generator.
These approaches increase the sustainability of the ADR process and the quality of team communication.
Stakeholder Participation and Communication in the ADR Process
Architectural decisions are shaped not only by technical teams but also by product managers, operations teams, and sometimes end-user representatives. Involving stakeholders early ensures that decisions align with business goals and that unexpected risks are identified beforehand. This participation increases the transparency of the ADR process and facilitates the long-term adoption of decisions.
Communication mechanisms must clearly outline how a decision was determined and why it was made step-by-step. Typically, sprint planning meetings, technical review sessions, and retrospectives are the main platforms where ADRs are kept up to date and stakeholder feedback is gathered. Adding a "Stakeholders" section to each ADR file to document who contributed, when, and in what format provides a reference point for future review processes.
Finally, stakeholder involvement should not be limited to making the decision; they should also play an active role in implementing the decision and monitoring its outcomes. This allows the expected value of the decision to be measured in real-time and restructured quickly if necessary.
Archiving and Accessibility of ADR Documents
ADR documents serve as a critical resource representing the history of a project's architectural evolution. The long-term accessibility of these documents is essential for new team members to quickly review past decisions and develop a deep understanding of the reasoning behind the current architecture. A good archiving strategy should include version control, metadata management, and search capabilities.
Git-based storage offers a natural environment for versioning ADR files. However, it is not sufficient on its own; when used alongside index files (e.g., index.md) and search engines (ElasticSearch, Algolia, or a simple GitHub search), it is possible to quickly find the history, status, and related code changes of a specific decision. The following JSON illustrates the basic structure of an ADR index:
{
"adr": [
{
"id": "0001",
"title": "Data Layer Choice",
"status": "Accepted",
"date": "2026-08-28",
"link": "/docs/adr/0001-data-layer-choice.md"
},
{
"id": "0002",
"title": "Logging Solution",
"status": "Superseded",
"date": "2025-11-12",
"link": "/docs/adr/0002-logging-solution.md"
}
]
}
This structure can be updated both manually and automatically during the CI/CD process. For example, a script can be run at the end of each pull request to ensure the index file is regenerated. This keeps the archive reflecting the most up-to-date decisions and accessible to team members at all times.
Risk Management and Rollback Plans in the ADR Process
Every architectural decision carries certain risks. Risk management in the ADR process involves the early detection, prioritization, and effective mitigation of these risks. During the risk analysis step, "What if" scenarios are created to determine the scope of potential failures and performance degradation. This analysis is directly reflected in the "Consequences" section of the decision, giving the team a perspective that goes beyond expected outcomes.
Rollback plans are critical safety nets when decisions do not yield the expected results. Backup strategies, data consistency tests, and automated rollback scripts allow the system to quickly return to its previous state. For example, while adding a NoSQL data layer, PostgreSQL's backup configuration is kept active simultaneously, and if a problem arises, the system reverts to the old structure simply by changing configuration files. Such plans should be detailed under a "Rollback" heading in the ADR documents, ensuring the team always has a clear action roadmap.
Risk management and rollback plans strengthen the sustainability of the ADR process. Anticipating the long-term impacts of decisions and being prepared for unexpected situations increases team confidence and guarantees project continuity.
Conclusion
ADR is a practice that ensures architectural decisions are transparent, measurable, and reversible. With a proper template, CI/CD integration, and regular review mechanisms, teams can adapt quickly to new requirements without losing the history of their decisions. The example scenario above demonstrates how a decision is documented, the validation steps, and a potential rollback process. This structure prevents decision chaos, especially in distributed systems, and builds a sustainable architecture.
Top comments (0)