Documentation-as-Code: Store Architectural Decisions in the Same PR as the Implementation, or Watch Onboarding Take 3x Longer

I need to talk about documentation because it’s genuinely the thing that makes or breaks developer experience — and with AI coding tools becoming mainstream, the stakes have never been higher.

The Documentation Crisis in 2026

Here’s a number that should bother everyone: the average developer spends 30-40% of their time searching for information. Not writing code. Not reviewing PRs. Not in meetings. Just… trying to figure out how things work, why decisions were made, and where the landmines are. This comes from multiple developer productivity studies, and it’s been consistent for years. We’ve made incredible progress on CI/CD, deployment automation, testing infrastructure — but documentation remains stuck in the dark ages.

And here’s the cruel twist for 2026: AI coding tools amplify whatever documentation quality you have, for better or worse.

When your codebase has good documentation — clear READMEs, well-explained architectural decisions, up-to-date API docs — AI agents like Claude Code and Cursor generate remarkably good code suggestions. They understand the context, they follow your patterns, they make architecturally consistent choices.

When your documentation is outdated, incomplete, or contradictory? The AI tools faithfully generate code based on those wrong assumptions. Bad docs lead to bad AI-generated code, which leads to more bugs, which leads to more firefighting, which leads to less time for documentation. It’s a vicious cycle, and I’ve watched it play out on three different teams this year.

Enter the ADR: Architectural Decision Records

The single most impactful documentation practice my team has adopted is the Architectural Decision Record (ADR). The concept is simple: every significant architectural decision gets documented as a markdown file, stored in the repo, and reviewed in the same PR as the implementation.

An ADR answers four questions:

  1. What was the decision? (e.g., “We chose PostgreSQL over DynamoDB for the orders service”)
  2. What was the context? (e.g., “We need ACID transactions for financial data, our team has deep SQL expertise, and our query patterns are relational”)
  3. What alternatives were considered? (e.g., “DynamoDB was considered for scalability but rejected because of transaction limitations and the team’s unfamiliarity”)
  4. What are the consequences? (e.g., “We accept the scaling limitations of single-node Postgres for now and will revisit sharding if we exceed 10M orders/month”)

That’s it. A single markdown file, typically 200-400 words, that captures the why behind a decision.

18 Months of ADRs: The Results

My team adopted ADRs 18 months ago, and the results have been transformative.

Onboarding time dropped from 6 weeks to 2 weeks. New engineers used to spend their first month asking “why did we do it this way?” for every major architectural choice. Now they read the ADR and understand the context, the alternatives, and the tradeoffs in 5 minutes. We went from 30+ Slack interruptions per new hire in their first month to fewer than 10.

AI code quality improved measurably. When engineers set up Claude Code or Cursor in our repo, the tools read our ADRs and generate code that’s architecturally consistent. Before ADRs, AI suggestions would sometimes recommend patterns we’d explicitly rejected (like suggesting DynamoDB for a service where we’d documented why we chose Postgres). The ADR serves as context that AI tools can leverage.

Decision revisitation dropped by ~70%. Before ADRs, we’d have the same architectural debate every 6-12 months because nobody remembered why the original decision was made. Now when someone suggests “we should switch from RabbitMQ to Kafka,” we point to ADR-023 which explains the original reasoning and what would need to change to justify a switch.

The PR Discipline

Here’s the rule that makes ADRs work: every PR that makes an architectural choice must include an ADR. No ADR, no merge.

What counts as an “architectural choice”?

  • Adding a new dependency
  • Introducing a new pattern (e.g., first use of event sourcing in the codebase)
  • Changing a data model in a non-trivial way
  • Choosing a new tool or service
  • Deviating from an established convention

This sounds strict, but in practice it adds maybe 15-20 minutes to a PR. Writing down “why I made this choice” forces clarity of thinking that often catches problems before they ship. I’ve seen engineers change their approach mid-ADR because the act of writing down their reasoning exposed a flaw they hadn’t noticed.

What ADRs Don’t Solve

I want to be honest about the limitations. ADRs capture point-in-time decisions, but they don’t solve the problem of evolving knowledge:

  • Runbooks for how to debug production issues still need a separate home
  • API documentation that changes with every release needs automated generation
  • Onboarding checklists that evolve as the team grows need a wiki or Notion-like tool
  • Architectural overviews that show how systems connect need diagrams that live outside markdown

ADRs are one piece of the documentation puzzle — arguably the most impactful piece — but they’re not sufficient on their own.

Tools That Make It Easy

If you want to get started with ADRs:

  • adr-tools: CLI tool for creating and managing ADRs with consistent numbering and formatting
  • Log4brains: A beautiful ADR viewer that generates a searchable website from your ADR files
  • Docs-as-Code with Docusaurus or MkDocs: For the broader documentation beyond ADRs
  • GitHub/GitLab PR templates: Add an ADR checklist item to your PR template so engineers are prompted to create one when relevant

The Question

How does your team handle technical documentation? Have you tried ADRs or a similar approach? I’m especially curious about how teams scale documentation practices as the codebase and team grow — what worked at 10 engineers doesn’t always work at 50.

Maya, I’m a total ADR convert and I want to share why from the perspective of someone who writes code every day, not manages teams.

The “Why Did We Use RabbitMQ?” Problem

Before my team adopted ADRs, I had a recurring experience that I think every developer knows: you’re working on a feature, you hit an architectural boundary, and you ask a colleague “why did we use RabbitMQ here instead of just a database queue?” The answer was always some variation of:

  • “I think James decided that, but he left two years ago.”
  • “There was a Slack thread about it… let me search… I can’t find it.”
  • “I’m not sure, it was before my time. Probably just ask in #engineering and hope someone remembers.”

The institutional knowledge was locked in people’s heads, and when those people left, the knowledge left with them. Every architectural decision became folklore — half-remembered stories passed down through Slack threads and onboarding conversations that got more distorted with each retelling.

Now I read the ADR. Five minutes. I know the context, the alternatives that were considered, and the specific tradeoffs that were accepted. It’s like having a conversation with the person who made the decision, except they wrote it down when the reasoning was fresh.

The Relitigating Problem (and How ADRs Fix It)

This is the biggest win I’ve experienced personally, and Maya touched on it: ADRs prevent endlessly relitigating old decisions.

Here’s a pattern I used to see every few months: a new engineer or a senior engineer returning from a different project would look at our message queue and say, “Why aren’t we using Kafka? Kafka is better for our use case.” This would trigger a 2-hour meeting where everyone debated RabbitMQ vs. Kafka, someone would volunteer to write a comparison doc, the doc would never get finished, and we’d table the discussion. Six months later, someone else would raise the same question and the cycle repeated.

With ADRs, the conversation goes like this:

“Why aren’t we using Kafka?”
“Check ADR-023. It explains why we chose RabbitMQ — specifically, our message volume is low enough that Kafka’s partitioning model adds complexity without benefit, our team has deep RabbitMQ expertise, and the routing flexibility of RabbitMQ exchanges matches our multi-tenant message patterns. If you think the assumptions have changed, propose a new ADR that supersedes it.”

That last part is key: ADRs aren’t permanent decrees, they’re documented starting points for future discussions. If our message volume grows 10x and the Kafka tradeoff changes, someone can write ADR-047 that supersedes ADR-023 with updated reasoning. The history is preserved, the decision evolves, and nobody wastes time re-deriving first principles.

My Favorite Unexpected Benefit: Better Code Reviews

Something I didn’t expect: ADRs dramatically improved our code review quality. Before ADRs, a PR with an architectural choice would trigger long review threads where reviewers questioned the approach, the author explained their reasoning in comments, and the same discussion happened across multiple reviewers. Now the ADR is in the PR — reviewers read the reasoning upfront, and the review conversation focuses on implementation quality rather than re-debating the approach.

It also helps junior engineers understand why code is structured a certain way, not just how. When I review a junior engineer’s PR and they’re following a pattern documented in an ADR, I know they understand the reasoning. When they deviate from the pattern, I can point to the ADR and ask “are you intentionally diverging from this approach, and if so, should we update the ADR?”

One Tip for Getting Started

If your team is skeptical about ADRs (mine was initially), start small. Don’t mandate ADRs for everything on day one. Instead, the next time someone asks “why do we do X this way?” and nobody has a clear answer — write the ADR retroactively. Once you have 10-15 of these retrospective ADRs, the team will see the value and start writing them proactively. That’s exactly how it happened for us.

I mandated ADRs across my entire engineering org about two years ago, and I want to be honest about how it went — because it wasn’t smooth, and the lessons from the bumpy adoption might be more useful than the success story.

The Rocky Start

When I announced “every architectural decision needs an ADR in the PR,” the response from my team was… not enthusiastic. The pushback fell into three categories:

  1. “This is bureaucracy.” Senior engineers felt like I was adding process for process’s sake. They’d been making architectural decisions just fine without writing them down, thank you very much.
  2. “I don’t have time for this.” Sprint commitments were already tight, and asking engineers to write a 200-word document for every significant PR felt like adding tax to their workday.
  3. “What counts as ‘architectural’?” The boundary was unclear. Is choosing between two npm packages an architectural decision? What about adding a new database index? The ambiguity caused friction.

For the first three months, compliance was maybe 30%. Engineers would submit PRs without ADRs, reviewers would let it slide because they didn’t want to be the process police, and the mandate was slowly dying through non-enforcement.

What Fixed It

Three things turned it around:

First, I wrote the first 20 ADRs myself. Not for new decisions — for existing decisions that the team had been wondering about. I went through our codebase and wrote ADRs for things like “Why we use a monorepo,” “Why the auth service is separate from the user service,” “Why we chose GraphQL for the client API but REST for inter-service communication.” Each one took me 15-20 minutes.

This did two things: it showed the team what a good ADR looks like (short, practical, no fluff), and it demonstrated that the format was genuinely useful. Engineers started saying “oh, that’s why we do it that way” — and that reaction sold the concept better than any mandate ever could.

Second, I made ADR review lightweight. The early ADRs were getting over-reviewed — people were treating them like design docs, debating every sentence, requesting multiple revisions. I clarified: an ADR review is a 5-minute sanity check. Does it capture the decision, the context, and the key alternatives? Yes? Approve it. It’s not a full design review; it’s a decision log.

Third, the new hire moment. About four months in, we onboarded a senior engineer named Daniela. In her first week, she read all 35 ADRs we had at that point. By week two, she was making meaningful contributions to architectural discussions because she understood the context. She told the team in a retro: “Those ADRs saved me a month of ramp-up. I’ve never joined a team where I understood the ‘why’ this fast.”

That story spread through the org and did more for ADR adoption than anything I could have mandated. Engineers who’d been resistant started writing ADRs because they saw the direct impact on a colleague’s experience.

My Current Approach

Today, we have 140+ ADRs across our main repositories. The adoption is close to 100% for significant decisions, though we still have debates about what qualifies as “significant.” My rule of thumb: if the decision would be hard to reverse in two weeks, it needs an ADR. Easy to reverse? Just do it and document later if it becomes a pattern.

I also encourage “lightweight ADRs” — sometimes just 3-4 sentences in a markdown file. Not every decision needs a multi-paragraph analysis. The important thing is that the decision and the primary reasoning are captured, not that we write a thesis.

Maya’s point about the AI benefits resonates with me. We’ve noticed that Claude Code gives noticeably better suggestions in repos with ADRs versus repos without them. The AI tools use that context, and it’s one of the most compelling arguments for ADRs in 2026 — you’re not just writing docs for humans, you’re writing context for the AI tools that your team uses every day.

I want to add the product perspective here because ADRs have been surprisingly valuable for my team too — and I have a request for how to make them even better.

How ADRs Changed Product-Engineering Conversations

Before ADRs, my product team had a recurring frustration. We’d propose a feature, engineering would push back with “we can’t do that because of how the system is architected,” and we’d get into an emotional standoff. Product felt like engineering was blocking progress. Engineering felt like product didn’t understand technical constraints. Nobody won.

The problem wasn’t that the constraints were wrong — it was that they were invisible to product. When an architect makes a decision to use event sourcing for the orders domain, that decision has downstream implications for what product can and can’t do easily. But product never saw that decision being made, never understood the reasoning, and only encountered the constraint when they proposed something that bumped against it.

ADRs changed this dynamic completely. Now when product asks “why can’t we add real-time inventory sync?” the answer isn’t “because engineering” — it’s “look at ADR-031, which explains that we chose eventual consistency for inventory updates because the cost of strong consistency at our scale would require re-architecting three services and add 200ms of latency to every write operation. Here are the specific tradeoffs, and here’s what would need to change if we want to revisit this.”

That turns an emotional debate into an informed discussion. Product can look at the tradeoffs and decide: is real-time sync important enough to justify the investment? Sometimes yes, sometimes no — but the conversation is rational and grounded in shared context, not a trust exercise.

ADRs Also Help Product Prioritize

Here’s something I didn’t expect: reading ADRs made me a better product leader. When I understand why the system is built the way it is, I can make smarter prioritization decisions. If I know from ADR-015 that the notification service was built with a specific scaling ceiling because the team chose simplicity over scalability, I can plan for the refactoring work before we hit that ceiling instead of treating it as a surprise when we get there.

It also helps me explain technical constraints to stakeholders — the CEO, the board, sales leadership. Instead of saying “engineering says it’s hard,” I can say “here’s the specific architectural decision that creates this constraint, here’s why it was made, and here’s what the investment looks like to change it.” That level of specificity builds trust between functions.

My Request: Include Product Rationale in ADRs

Here’s where I’d push the ADR format further: include the product rationale alongside the technical rationale.

Most ADRs I’ve read focus exclusively on technical tradeoffs — performance, scalability, team expertise, operational complexity. But many architectural decisions are also shaped by product context: which customer segment we’re targeting, what the competitive landscape looks like, which use cases we’re prioritizing.

For example, an ADR that says “we chose PostgreSQL over DynamoDB” might include the technical reasoning (ACID transactions, team expertise) but miss the product reasoning (our enterprise customers require audit trails that are easier to implement with SQL, and our roadmap for the next 18 months is reporting-heavy which favors relational queries).

When both the technical and product rationale are captured, the ADR becomes a complete record of the decision — not just how we built it, but why this approach serves our users and business strategy. And when conditions change (we pivot to a different customer segment, or the competitive landscape shifts), the product context in the ADR helps the team assess whether the decision still holds.

My suggestion for an enhanced ADR template:

  1. Decision — what we chose
  2. Technical context — engineering constraints and tradeoffs
  3. Product context — business rationale, customer needs, competitive factors
  4. Alternatives — what else we considered (both technical and product alternatives)
  5. Consequences — what this enables and what it constrains, for both product and engineering

Maya, would your team be open to including product rationale in ADRs? I think it would strengthen the bridge between product and engineering and make ADRs a true cross-functional artifact rather than just a technical document.