Introduction: Why Large ADR Libraries Become a Liability

Architectural Decision Records (ADRs) are a proven mechanism for capturing the rationale behind significant technical choices. Yet as a system grows, so does its ADR collection. A library that starts with a dozen well-crafted records can balloon into hundreds or thousands of files within a few releases. Without deliberate governance, this accumulation turns into decision debt: duplicates appear, context goes missing, and team members waste time searching for the “why” behind an architectural choice. This article expands on foundational best practices to help engineering organizations keep ADR libraries organized, discoverable, and valuable at scale.

The ADR format itself, popularized by Michael Nygard and later refined by Joel Parker Henderson, is designed to capture context, options, and outcomes. When a library exceeds several hundred records, the same principles that make a single ADR useful—clarity, traceability, and succinct rationale—must be applied to the collection as a whole. The goal is to transform a potential liability into an asset that speeds onboarding, supports architectural analysis, and prevents repeated mistakes.

Foundations: Consistent Naming Conventions That Scale

A predictable, unambiguous naming scheme is the bedrock of a navigable ADR library. Without it, even a well-structured folder hierarchy becomes confusing. The pattern you choose must encode enough information to allow quick mental sorting and ensure uniqueness.

The most widely adopted scheme is NNNN-title-with-hyphens.md, where NNNN is a zero-padded sequence number. For example, 0001-use-postgresql-for-user-data.md. This ensures natural sort order and global uniqueness within a repository. For libraries that span multiple years or large teams, consider prepending a date in ISO 8601 format: 2024-03-15-0032-migrate-to-kubernetes.md. This temporal prefix allows you to browse decisions by time even if the sequence numbering resets.

Anti-Patterns to Avoid

  • Using short, ambiguous titles0001-database-choice.md does not differentiate between multiple database decisions. Be specific: 0001-use-mysql-for-user-profiles.md.
  • Allowing special characters – avoid spaces, parentheses, and accented characters. Stick to hyphens, underscores, and ASCII letters.
  • Renaming existing files – once an ADR is merged, its filename becomes a permanent identifier. Renaming breaks links and confuses history.

Handling Name Collisions

When two decisions have similar titles, append a disambiguation suffix such as the affected component or domain: 0047-cache-strategy-auth-service.md vs. 0048-cache-strategy-reporting-service.md. Adopt this practice from the start to avoid a painful migration later.

Repository Structure: Flat vs. Hierarchical

The physical organization of ADR files on disk directly affects how quickly team members locate relevant records. Two primary approaches exist, each with trade-offs.

Flat Directory with Metadata

For teams with fewer than 200 ADRs, a single flat directory inside the repository—e.g., docs/adr/—works well. All decisions live in one folder, and metadata (tags, status, lifecycle stage) is embedded in front matter or a companion index. This simplicity avoids nested folder traversal and makes bulk operations (like grep searches) trivial.

Hierarchical Organization

When the ADR count surpasses several hundred, grouping files by domain, subsystem, or lifecycle stage becomes beneficial. Common patterns include:

  • By domain: docs/adr/domain/user-management/, docs/adr/domain/payments/
  • By lifecycle: docs/adr/proposed/, docs/adr/accepted/, docs/adr/deprecated/
  • By release: docs/adr/release-3.2/, docs/adr/release-4.0/

Whichever approach you choose, document the rationale in a README.md inside the ADR directory and enforce the structure with repository linting rules (e.g., using pre-commit hooks or CI checks). This prevents drift as new contributors join.

The Case for an Index File

Regardless of structure, maintain an index.md or SUMMARY.md that lists all ADRs with their number, title, status, and a one-sentence summary. Automate generation using a pre-commit hook or CI job that runs a script to compile the list. Tools like adr-tools can generate this index automatically. The index serves as a quick dashboard, allowing anyone to see the library’s scope at a glance.

Rich Metadata and Controlled Tagging

Filenames provide only a narrow window into content. Structured metadata unlocks powerful filtering and cross-referencing. Adopt a consistent metadata block at the top of each ADR (YAML front matter is standard). Essential fields include:

  • Title – short, human-readable decision name
  • Status – Proposed, Accepted, Deprecated, Superseded
  • Date – YYYY-MM-DD of creation or last significant change
  • Tags – controlled vocabulary terms (e.g., database, security, api-design)
  • Authors – list of decision owners
  • Deciders – stakeholders involved in the decision
  • Related ADRs – sequence numbers of linked records

Tagging Best Practices

Tags are especially powerful for large libraries. Use a controlled vocabulary to prevent tag explosion. Start with a small set of high-level categories (e.g., infrastructure, data-model, integration) and allow domain-specific sub-tags only when justified. Tools like ADR Tools support tag-based filtering natively. For custom implementations, a simple grep across metadata can be scripted, but a dedicated static site generator (like Log4brains) offers a much better search experience.

Cross-Referencing and Decision Graphs

When an ADR supersedes or amends another, include a reference line in its metadata: Supersedes: ADR-0023 or Related: ADR-0010, ADR-0012. This builds a directed graph of decisions. Over time, this graph helps newcomers understand how a design area evolved—why one technology was chosen, then later replaced, and what trade-offs were considered at each step. A tool like Log4brains can visualize this graph automatically.

Version Control as the Source of Truth

ADRs stored in version control benefit from the same practices as source code: branching, pull requests, and CI validation. Git is the most common choice, but the principles apply to any VCS.

Branching and Pull Request Workflow

Treat ADR proposals like code changes. Create a branch (e.g., adr/0047-oauth-migration), draft the document using a template, and open a pull request. Require reviews from at least one engineer outside the immediate team to catch blind spots. Use the PR comment thread to discuss rationale—these discussions become a valuable supplement to the record. Merge only after consensus is reached.

CI Validation

Set up a CI pipeline that validates each new ADR: checks for required sections (Context, Decision, Consequences), validates date format, ensures the sequence number has not been used before, and verifies that internal links are not broken. This automated gate keeps the library consistent and reduces the burden on human reviewers.

Changelog Integration

Link ADR changes to your release changelog. When an ADR is accepted, add a note like “Decision: ADR-0047 – Migrate user authentication to OAuth 2.0.” This connects the technical decision to user-visible changes in each release, making it easy to trace why a feature was implemented a certain way.

Commit History Hygiene

Encourage the team to commit ADR updates independently of code commits. Use commit messages like “docs(adr): add ADR-0048 for cache strategy” or “docs(adr): supersede ADR-0012 with ADR-0087”. This keeps the decision history clean and auditable, and git blame remains a reliable tool for tracing who changed what and when.

Automating Lifecycle Management

Manual maintenance of a large ADR library is error-prone and leads to stale records. Automation addresses the most common pain points.

Generation and Templating

Use a tool like adr-tools or adr-cli to scaffold new ADRs from a standard template. The template should include the metadata block, a Context section, Decision, and Consequences. Automation ensures consistency and reduces friction for contributors.

Index Regeneration

Set up a scheduled job (e.g., a GitHub Action running daily) that regenerates the index.md file. This action can also flag ADRs that have been in “Proposed” status for more than 90 days, prompting a review or automatic deprecation. Some organizations use a cron job that sends a Slack reminder to the ADR steward.

Large libraries often contain internal links to other ADRs that break when a file is renamed or removed. A scheduled script (e.g., markdown-link-check) can report broken references and prevent the library from degrading. Integrate this into your CI pipeline so that every PR is checked for link integrity.

Status Transitions

Automate status changes. For example, when an ADR is marked “Superseded,” a script can update the superseding ADR’s metadata to include a Supersedes field and move the file to an archived directory. This keeps the active library focused on current decisions while preserving historical context.

Regular Review and Archiving Processes

An unmaintained ADR library loses trust. Teams stop reading it because they assume the information is outdated. A disciplined review cycle prevents this.

Scheduling Quarterly Reviews

Assign a rotating ADR steward who reviews the entire library every quarter. The steward checks each ADR’s status, verifies that the decision still holds, and updates metadata if necessary. For very large libraries (500+ ADRs), prioritize reviewing ADRs that are over one year old or that have been flagged as potentially outdated by automation.

Deprecation and Archiving

Decisions that are no longer relevant should be clearly marked. Use a status field like Deprecated or Archived. Move such ADRs to a docs/adr/archived/ folder but retain a stub in the index with a link to the archived file. This preserves historical context without cluttering the active set.

Example: ADR-0032 originally chose MongoDB. Two years later, ADR-0087 opts for PostgreSQL. The new ADR explains why MongoDB no longer fits (e.g., data consistency requirements). The old ADR is updated to Superseded by ADR-0087. Anyone reading ADR-0032 immediately sees that the decision is outdated and finds the current one.

Choosing the Right Documentation Platform

ADRs stored as plain Markdown in a repo are accessible to any developer with a text editor, but for team-wide consumption, a searchable, browsable interface significantly improves usability.

Repository-Based Platforms

GitHub/GitLab/Bitbucket – The built-in Markdown rendering and file browser are sufficient for small teams. Use repository wikis or the /docs folder. Advantages: no extra tooling, version control history is native. Disadvantages: limited search across many files, no tag-based filtering, and no graph view.

Dedicated ADR Tools

  • ADR Tools – CLI-based, simple, perfect for teams already using the command line. It supports templating, index generation, and basic filtering.
  • Log4brains – Open-source ADR manager that generates a static site with full-text search, tag filtering, a graph of decision relationships, and integration with Git. Excellent for cross-referencing.
  • Decision Record – Another open-source option that integrates with Git and provides a web UI.

General Documentation Platforms

Tools like Confluence, Notion, or Outline can host ADRs, but they lose tight integration with code repositories. If you choose a wiki platform, ensure every ADR has a unique ID (the sequence number) and that version history is enabled. Use automation to sync ADRs from your repo to the wiki to maintain a single source of truth. Be aware that wiki platforms often lack powerful API-level search across many pages.

Collaborating on ADRs at Scale

Large libraries mean many contributors. Without a clear workflow, ADR quality degrades and conflicts arise.

Guidelines for Contributors

Publish a short set of contribution rules: how to propose a new ADR, what metadata must be included, and how to handle superseded decisions. This is typically placed in CONTRIBUTING.md inside the docs/adr/ directory. Include a link to a template file and a decision flow diagram.

Review Process

Require at least one review from someone outside the immediate decision team. This catches missing context, alternative options, and potential biases. For architecture-level decisions, involve the principal engineer or architect. Use pull request comments to discuss rationale—these discussions are themselves a valuable record. After a decision is accepted, archive the PR discussion in the ADR itself (via a link or summary).

Handling Conflicts

When two ADRs propose conflicting approaches, resolve by explicitly superseding the earlier one or by creating a new ADR that combines the best aspects. Never leave two “Accepted” ADRs on the same topic; this confuses future readers. The decision lineage should be clear: a new ADR should explain why the old approach no longer works and how the new one addresses the concerns.

Measuring ADR Library Health

To know whether your management practices are effective, track a few key metrics:

  • Stale ADR ratio – percentage of ADRs with status “Proposed” and older than 6 months. Set a goal under 10%.
  • Search time – how long a team member needs to find a decision on a specific topic. Use surveys or observe navigational patterns. A target is under 30 seconds for the most common topics.
  • Link integrity – number of broken internal references. Should be zero. Use automated checks to enforce this.
  • ADR growth rate – decisions per month. If this grows too quickly (e.g., more than 10 per month for a small team), you may be capturing too many trivial choices. Encourage teams to use light-weight tickets for minor decisions and reserve ADRs for architecturally significant ones.
  • Time from proposal to acceptance – if this exceeds two weeks, the review process may be a bottleneck. Consider asynchronous reviews with clear deadlines.

Periodically share these metrics in team retrospectives to reinforce the value of the ADR process and to identify areas for improvement. Use dashboards (e.g., in GitHub Insights or a custom Grafana panel) to visualize trends.

Conclusion: From Accumulation to Asset

Large ADR libraries do not have to become a burden. When you apply consistent naming, structured organization, rich metadata, version control discipline, automation, and regular reviews, the library becomes a first-class artifact that accelerates onboarding, supports architectural analysis, and prevents teams from repeating past mistakes. The investment in managing ADRs at scale pays off each time someone finds the answer to “Why did we do it that way?” in seconds instead of hours.

Start small: pick one practice from this list—perhaps implementing an index file or a CI validation check—implement it in your repository, and iterate. Over time, your ADR library will evolve from a bloated storage room into a well-indexed decision archive that your whole team relies on.

For further reading on ADR patterns and tooling, explore the ADR website and the original specification by Joel Parker Henderson. Additional insights on handling decision debt can be found in this InfoQ article.