Latest / Tech Leadership with Fexingo: Engineering Managers, CTOs, and Technical Leadership Conversations / How We Use Architectural Decision Records
Transcript
- Lucas: So I want to talk about something that sounds boring on paper but has saved my teams more time than any single tool or process change: Architectural Decision Records. ADRs. Luna: I've heard the term — lightweight docs that capture why you made a technical choice. But I'll be honest, I've never actually seen one work in practice. Lucas: That's exactly why I want to get into it. Because most engineers I talk to nod along and say 'yeah, we should do that' — and then they don't. Or they do it badly. And then they give up. Luna: What's the bad version look like? Lucas: A fifteen-page document that nobody reads, written after the decision is already made, usually by one person who then leaves the company. Or it's a Slack message that gets buried. Or it's nothing at all, which is actually the most common. Luna: Okay, so what's the good version? Give me a concrete example. Lucas: Let me tell you about a startup I consulted with last year. They had a classic problem: their database started slowing down under load. They were on Postgres, and someone suggested moving to a sharded MySQL setup. A senior engineer spent two weeks building a proof of concept, presented it, the team debated it for another week, and then they decided not to go ahead. Stuck with Postgres, optimized some queries, problem solved. Luna: That sounds reasonable. So what went wrong? Lucas: Six months later, a new engineer — let's call her Priya — encountered the same slowdown. Nobody remembered the earlier debate. The proof of concept was gone. The Slack thread had been archived. So Priya independently started investigating the same sharded MySQL approach. She spent three weeks on it before a senior engineer happened to mention 'oh yeah, we looked at that last year.' By then, she'd already burned the time. Luna: Oof. So the ADR would have captured that? Lucas: Exactly. If they'd written a one-page ADR titled 'Reject Sharded MySQL for Postgres Optimization' with the context, the options considered, and the reasoning, Priya would have found it in ten minutes and moved on. Instead, she lost three weeks. Luna: Okay, I'm sold on the concept. But what actually goes into a good ADR? Is there a standard structure? Lucas: There's a very lightweight template that's become pretty standard — originally from a ThoughtWorks engineer named Michael Nygard. The ADR is a single text file with five sections: title, status, context, decision, and consequences. Luna: That's it? Five sections? Lucas: That's it. The title should be short and descriptive — something like 'Use Postgres with Read Replicas Instead of Sharding.' The status is one of: proposed, accepted, deprecated, or superseded. Context explains the problem and the forces at play. Decision states the chosen option and the rationale. Consequences describe the trade-offs — what you gain and what you lose. Luna: So the status field lets you track the lifecycle of a decision over time. That's clever. How does that work in practice? Lucas: You start an ADR as 'proposed' when you're still debating. Once the team agrees, it becomes 'accepted.' Later, if you find a better approach, you mark the old one as 'superseded' and link to the new ADR. If you later decide the decision was flat-out wrong and you're going back, you mark it as 'deprecated.' Luna: That's really clean. It's like git history for your architectural thinking. Lucas: That's exactly the metaphor. And that's why the best practice is to store ADRs in a markdown file in your code repository — typically in a folder called docs/adr. They're version controlled right alongside the code that implements the decision. Luna: So when someone joins the team, they can just browse the ADR folder and get a quick history of all major architectural decisions. That's powerful. Lucas: It's the fastest onboarding tool I know. I've seen teams cut ramp-up time by weeks because new hires can read the ADRs and understand not just what the system does, but why it's built that way. Luna: Let me push back a little. This sounds like overhead. Engineers are already stretched thin. Are you saying they should stop coding to write documents? Lucas: I hear that objection all the time. But here's the thing: you're already having the conversations. The debate, the whiteboarding, the Slack threads — that time is spent whether you document it or not. An ADR just captures the output. It takes maybe thirty minutes to write a good one. And it saves hours or weeks of re-debate later. Luna: So the investment is front-loaded, but it pays back fast. That makes sense. Do you have a rule of thumb for when an ADR is warranted? Lucas: My rule is: if the decision will take more than thirty minutes to undo, write an ADR. That includes choosing a database, a framework, an API design pattern, a caching strategy — anything that has long-term consequences. But you don't need an ADR for whether to use tabs or spaces. Luna: Right, that would be overkill. So what does a good ADR look like in practice? Can you walk me through the one from the startup example? Lucas: Sure. Title: 'Use Postgres Read Replicas Instead of Sharded MySQL.' Status: 'Accepted.' Context: 'Our primary Postgres database hits 80 percent CPU during peak traffic. We need a solution that scales reads without increasing write latency. Options considered: sharded MySQL, read replicas on Postgres, and caching via Redis.' Luna: And the decision section? Lucas: Decision: 'We will add two Postgres read replicas and route all read-only queries to them. We will implement Redis caching for frequently accessed data. Sharded MySQL was rejected because it would require a full migration, increase operational complexity, and the team lacks MySQL expertise.' Luna: And consequences? Lucas: Consequences: 'Positive — lower latency for reads, no schema changes, minimal operational overhead. Negative — eventual consistency for cached data, need to update connection pooling config, additional monitoring for replica lag.' And that's the whole ADR. One page, maybe ten sentences total. Luna: That's remarkably concise. I can see why someone would actually read that. What about the inevitable question of 'who writes the ADR?' Lucas: The person proposing the decision writes it. That could be a senior engineer, a tech lead, or even a junior engineer who's researched an option. The act of writing forces clarity. I've had situations where someone started writing an ADR and realized mid-way that their preferred option didn't actually hold up under scrutiny. Luna: So the ADR becomes a thinking tool, not just a record. I like that. Lucas: Exactly. And it democratizes decision-making. A junior engineer can propose an ADR just as easily as a CTO. The status field tracks whether it's accepted, so there's a clear record of the outcome. Luna: One challenge I've seen is that teams start strong with ADRs but then the practice fades. How do you make it stick? Lucas: You make it part of the engineering workflow. Don't treat it as extra work — treat it as a required artifact for any non-trivial change. Some teams enforce it in code review: if your pull request implements a change that should have an ADR, the reviewer asks for it before approving. Luna: That's a strong signal. But it also requires buy-in from the whole team, especially the tech lead. Lucas: Absolutely. The tech lead or CTO has to model the behavior. If they write ADRs for their own decisions and reference them in meetings, the team will follow. It's a culture thing more than a process thing. Luna: I want to circle back to something you said earlier — about the ADR preventing re-debate. That's a huge time saver, but I wonder if it can also stifle healthy discussion. What if a decision needs to be revisited because circumstances changed? Lucas: That's why the status field has 'superseded.' You don't re-debate the old decision from scratch. You write a new ADR that explains why the conditions have changed — say, the company grew from one million to ten million users — and mark the old one as superseded. The conversation is anchored to the new evidence, not a rehash of old arguments. Luna: So it channels the debate productively. That's a good distinction. Lucas: I've seen teams that use ADRs for everything from choosing a cloud provider to deciding on a logging framework. Over time, the ADR folder becomes the single source of truth for architectural history. It's invaluable during audits, acquisitions, or when a key person leaves. Luna: Speaking of leaving — I think that's one of the strongest arguments. Knowledge walking out the door is a real risk. And ADRs are cheap insurance. Lucas: Right. If you're a startup and your CTO leaves, the next person isn't starting from zero. They can read the ADRs and understand why the system is the way it is. Luna: There's something about this that reminds me of why we keep this podcast ad-free. We want the content to be useful and timeless, not driven by sponsors. And if listeners find value in episodes like this, there's a way to support that. Lucas: Yeah, and it's really simple. If today's conversation about ADRs gave you something practical, you can buy us a coffee at buy me a coffee dot com slash fexingo. That's what keeps the show independent and focused on topics like this rather than ad reads. Luna: We don't do any of that listener-perk stuff — no bonus episodes or shout-outs. Just the satisfaction of knowing you're helping us keep the podcast free for everyone who finds it useful. Lucas: Exactly. And now back to ADRs — I want to talk about one more practical tip: numbering them. Use a sequential prefix like 0001-use postgres read replicas.md. That way they stay sorted and you can easily reference ADR 0001 in future documents. Luna: So the file name itself is a mini-index. That's elegant. Lucas: And when you supersede an ADR, you add a line in the old one that says 'Superseded by ADR 0012' and a link. That creates a navigable history. Luna: I'm now thinking about how to introduce this to a team that's never done it. What's the minimum viable start? Lucas: I'd say pick a single decision that's currently being debated — maybe a database choice or an API design — and write one ADR together as a team. Use the template. Make it a thirty-minute exercise during a tech huddle. Then put it in the repo. Let people see how simple it is. Luna: And if it works, do it again for the next decision. Over time, it becomes a habit. Lucas: Exactly. And you don't need to retroactively document every past decision. Just start now. Future you will thank present you. Luna: I like that. One last question: any tools that automate parts of this? Like generating a table of contents or tracking status changes? Lucas: There are several — adr-tools, a command-line tool that scaffolds the template and manages numbering. Some teams use a GitHub action that lists all ADRs in the README. But honestly, plain markdown and manual numbering work fine for most teams. The tooling isn't the hard part; it's the discipline. Luna: So the barrier to entry is almost zero. A text file and a folder. Lucas: That's the beauty of it. No new tool to learn, no subscription, no integration. Just a markdown file that lives with your code. And if you ever migrate to a different platform, the ADRs come with you. Luna: I have to say, I came into this episode skeptical, but I'm leaving convinced. I think I'll write my first ADR this week. Lucas: That's the best outcome I could hope for. And when you do, the rest of the team will see the value faster than you expect. One good ADR is worth a hundred Slack messages.