Hacker News new | past | comments | ask | show | jobs | submit login
Why Write ADRs (github.blog)
207 points by imsky on Aug 13, 2020 | hide | past | favorite | 61 comments



These articles about engineering process always put the responsibility solely in the implementing engineer's lap. Always more and more work to achieve JPL-level capability maturity, no matter your budget or headcount. Of course we want unit tests for every case, and verbose explanation in every atomic commit message, and architecture documents that are seldom read before they become stale. But make sure you also get your story points done for this sprint and meet your OKRs for this quarter.


> But make sure you also get your story points done for this sprint and meet your OKRs for this quarter.

The problem here is the points aren't measuring quality, they are measuring a type of velocity that doesn't take into account quality if you aren't getting points for that work.

Read: PMs often drive a timeline that accepts engineering risk, but not responsibility for that decision when it doesn't work.


This is fundamentally missing the point about what story points are, and goes to show you’re unfortunately stuck in another of the many companies using them poorly.

Many (poor) product managers look at velocity dropping and blame the team, or try to pack sprints. In fact, this is the time to open dialogue with the team and get to the bottom of why.

Often, it’s because tech debt or poor architecture is making it difficult to implement even simple features. The team might be burning out. There might be an overwhelming number of bugs and support tickets that need to be addressed.

Story points aren’t a target to hit, or even a KPI. They’re a barometer for team and process health. Unfortunately most engineering and product managers either don’t get it, or are unable to appropriately communicate that fact upwards.


I can only directly relate to solo/small-team projects:

I find writing text (preference: Markdown) and sprinkling it with visualizations (tables, graphviz...) to document stuff very useful and productive.

I don't see this as a burden but rather the opposite. A good portion of programming is not writing code, but thinking and communication. Using text as a direct output of this process helps in many areas. Mostly because we have a limited capability of keeping stuff in our heads at any given time.

A typical categorization of these documents would be:

- specification: describing the thing you build in detail

- todo-lists: organizing actions

- guides/instruction: describing usage of the thing you build in a accessible manner

- meeting & discussion protocols

The thing is: None of these things are extra or can be avoided. The only difference is whether you write them down or not.

The article describes something I would put into the fourth category, or maybe a fifth where you describe intent historically (like design documents).

I personally don't write design-documents or ADRs, nor have I ever seen them. But I assume that these become valuable in larger organizations and teams with a higher communication overhead. As soon you need to talk about these things over and over you want to write these down.


> As soon you need to talk about these things over and over you want to write these down.

This is the relevant part, to me. Can we do this documentation process JIT when someone asks about it? Maybe even convert the dialogue (in chat) or transcript of the conversation into the documentation.


I just started to write anything down basically...

When a collaborator or client talks to me or when I think about something, then I open a markdown file (first often just a notes.md) and just write in bullet points, and gradually organize it into categories.

I put these in version control as well since a while.

Thought experiment: if something is not worth writing down, is it worth discussing?


> Thought experiment: if something is not worth writing down, is it worth discussing?

Writing things down in a way that can be consumed by others is usually significantly more work than discussing that same thing live (whether in text or verbally). As such, I would say that the answer is obviously yes.


Yes, there are many things worth discussing which would be better left not written down.


Not really because there isn't a JIT budget in most projects, and they usually only get allocated via escalations, some of which imply doing the work for free.


I've been intrigued by ADRs for a bit, and this post prompted me to start a conversation with my current team. Quoting something I posted in my internal slack:

> Note that my goal, with ADRs, is not to increase the amount of time we spend on decisions! If the answers are "I didn't think too deeply and I'm going with my gut" it's still better to have that documented. If we find that we're getting bit by bad decisions, we can look at how those decisions were made and how we can improve them at that point, with much more context.


what you mention are real pain points, though from my experience they actually were a lot simpler than locking info away in some external tool. there is very little additional cognitive cost with adr's and from what I've experienced they add other value too such as a record of why things were done which saves a lot of time when you're ramping up and onboarding new team members who have a tendency to discuss why things are done in a specific way and not another. when used correctly they're not just another thing to take care of but an actual time saver (have personally avoided many meetings by simply pointing new people to them - and they have the benefit of structuring and capturing the architecture discussions in a central place right next to your code ... (if the git log history isn't enough for us we use gitlab comments on changes the same way we would use it on code). it's brilliant because it's so simple imo.


I think whether you use adrs or comments or git messages or readmes or whatever, the fundamental rule is simple:

In any case where you're making a non-default choice in software, it needs to be explained in an easily-discoverable place so a developer that's looking at the project and trying to understand the why of something can see it.

Too often I block PRs with confusing code and ask why it was done this way and the developer swings by my office or gets defensive and I have to say "no, I'm not attacking your code as being wrong, and I don't want a verbal explanation as to how it works. I want the decisions that led you to do it this way to be documented".

...

But actually usually the code is just wrong.


This is far from the first time I've evangelized this paper here on HN... but I think the ideas of the OP and the Naur paper "Programming as Theory Building" have a high degree of overlap. Indeed, at some level, the Naur paper deals with identifying the problem while the OP deals with practices to bridge the knowledge gap identified in the paper.

http://pages.cs.wisc.edu/~remzi/Naur.pdf


Thanks for the recommendation! Already enjoying this!


There are also plain text versions of that paper if you're interested:

- https://pastebin.com/raw/WwXKAGnW

- https://gist.github.com/onlurking/fc5c81d18cfce9ff81bc968a7f...


Quite ironically (given it's Github who are defending ADRs in the article), I avoid ADRs by using Github more richly: before working on a branch at all I create a substantial issue (think: multiple paragraphs, links to related issues/PRs, etc) and try to ping the team for feedback.

The design process will ideally happen asynchronously, as comments posted in the issue.

That way, a truthful trail of diverse considerations will be left in written form.

Contrariwise, ADRs can be too written excessively after-the-fact, by a single person. I have seen them degenerate into bureaucracy ("we designed X because X seemed the best option"... how informative).


> "we designed X because X seemed the best option"... how informative

If that's the most they can say, I'd rather that be surfaced. Knowing the decision was made in haste, with shallow consideration, is better than wondering if it was. And actually, that's probably the right way to make some decisions, if they seem likely to have a small difference in value between the many options it doesn't make a lot of sense to burn too many cycles making sure of that.

Once decisions come around to bite you, you can start to look at whether the decisions that are actually proving costly were the ones that were made lightly.

At least, that's how I'm thinking about it before getting into the weeds of it.


> That way, a truthful trail of diverse considerations will be left in written form.

But isn't that just an organic ADR?


I started a new job about six months ago and the engineering org writes ADRs. As a new hire, this was incredibly useful to understand some of the hows and whys of past decisions that would normally take me years to discover or understand.


I started a new job about two months ago and completely agree. The ADRs and Feature Specs have been immensely helpful in getting context around why certain decisions were made and the tradeoffs considered when making decisions.

It's especially useful because I joined the team during Covid and haven't actually met anyone else in person yet. I can't just turn around in my chair and ask someone at the desk next to me why something is the way it is. Now it involves pinging someone, setting up a zoom call, etc.


I joined a place recently and there was zero documentation, zero ADRs, zero discussions logged except vaguely in Slack, etc. Consequently I was completely baffled about why everything was as it is for the first few months ("Where do I find a network?" "It's in the frobnob_stash table under 'lemon'." "Oh, yeah, OBVIOUSLY.")


So this is somewhere between code comments and Confluence pages. Seeing as even comments can get stale, how accurate do these docs stay?

The added focus on "why" instead of "what" seems more resistant to cruft.


>Seeing as even comments can get stale, how accurate do these docs stay?

Part of the idea is that they're immutable, append-only. They express why an architecture / decision was made, when it was made.


Not that it takes anything away from your point, but to be slightly more precise, the content should (probably, see below) be treated as immutable. The metadata, included in the same files, is mutable - things like status, related ADRs, superseding PRS, etc.

Above I said probably - I'm not sure that we shouldn't allow editing when it's purely clarification, communicating more clearly what it already communicated to most of the audience.

An append-only section for adding further observations, as the decision plays itself out, is also an interesting option, although I don't know whether it would actually be more valuable than distracting.


They are not supposed to be updated. It captures a decision at one point in time with lots of context.

If an update is necessary, you create a new ADR.


If comments on the same line (or an adjacent line, such that it shows up in `git diff` output and the default code review display) get stale then that is a pretty bad failure of both the programmer and the reviewer(s); in my experience that doesn't happen very often.

A much bigger issue is comments that are a few lines (or a few tens of lines) away from some piece of what they're talking about. Then, they suffer from exactly the same issue as documentation anywhere, inside the repo or out: something drew the developers attention to the code that needed to be changed, but then there was no reason they should have known to look in this particular other location for text talking about what they changed. That's not the programmer's fault, unless we want our programmers to take the time to review every piece of documentation for anything that might need to be changed. I'd guess there are some contexts where that's appropriate, but I haven't ever worked in one.

Alternatively, we could have it be someone's job to own the docs, continually run over them and make sure they still apply, and stay abreast of PRs as they merge. I haven't seen that tried - it might be valuable if it was a role someone wanted.

What I've been trying is adding cross-references to my code, so that something can always be visible on the line or a neighboring line that notes that there's something relevant in another place. This is then checked in CI for integrity, and references that appear in the diff have their referents surfaced on the PR for the benefit of the reviewer. So far the links are pretty sparse, but have already been somewhat valuable. I intend to piggyback on the same system as I introduce ADRs.

I'd like to release the above tooling as F/OSS but really the trickiest parts are CI integration. The check is literally piping git diff to grep, looking for things of the form ^^{some label} and finding the associated @@{some label}. I decorate the PR on github with annotations through the Git Checks API.


Yes, I think of them as blogs. New engineers can read along and see the evolution of thoughts and design decisions.


Shout out to my pal Joel, who was in this space for awhile already! https://github.com/joelparkerhenderson/architecture_decision...


The “whys” here all sound sensible, but I’d be even more interested in _how_ people are implementing a process around ADRs, where you’re keeping them, etc.

At work we have a decent PR template that prompts people to provide context, alternatives considered, and underlying reasons for the change, which works pretty well. I’m trying about how or whether ADRs would function better, or if they would operate at a slightly higher level of change (i.e. for work that extends across multiple PRs).

I’d be interested in thoughts or experience people have, especially in medium or larger organizations.


I'm the software architect in a automotive project with ten teams. We use Confluence to write ADRs. We only use this process for changes which affect multiple teams.

Pro: Wysiwyg is great for editing it live in meetings, plugins like Gliffy are nice for diagrams, integration with Jira, accessible with a simple link.

Con: Not good enough for long term archival, so we export them to pdf regularly, wiki has no atomic commits.

We have a regular meeting where the team architects together discuss and ultimately approve these documents.


I recently rolled off a sweet FinTech project with a Fortune 500 bank’s Emerging Technologies team which has the best ADR implementation I’ve seen thus far.

Just fyi, these ADRs, written in Markdown, are kept in separate repo with special Markdownlint rules applied to ensure consistent formatting. But what made this team’s ADR implementation stand out to me were not the technical details of how they were maintained, but rather the SOPs they’d strictly adhered to.

In essence, they had a very academic perspective on ADRs, viewing them more like a potentially publishable white-paper- not necessarily in terms of length or formality, but procedurally. The rule we followed was that a spike should lead to an ADR, which made writing an ADR much more of a build-measure-learn cycle and kept quality high, since authors weren’t scrambling to remember their entire thought process after the fact. This also greatly improved the quality of the spikes themselves, as we spent less time falling down rabbit holes. Basically, a spike became strictly a determination of either feasibility or implementation, with an explicit record of that the determination and the way in which it was made, as well as the other trade-offs considered.


I'm personally a huge fan of the SPADE framework from Gokul Rajaram. First Round has a really good write-up on how to use it. [1] It serves both as an ADR and also a framework for making that decision in the first place, in one. I've introduced this at a few places I've worked and it's been very well received.

[1] https://firstround.com/review/square-defangs-difficult-decis...


At Khan Academy, we've been using ADRs for three years now, using Michael Nygard's format as a starting point. We adopted ADRs at the same time we adopted DACI (Driver, Approver, Contributors, Informed) as a decision making framework across the organization, so our ADRs server both of these purposes as well.


I’m hoping to implement this in my organisation very soon. There are still a couple things I need to figure out:

1. How do I articulate the criteria for when a decision should have an ADR?

2. I always see ADRs in the context of recording what was decided, but I’d like them to be raised more like requests for comments (RFCs) for a week or two first, particularly in cases where there may be impacts on other systems, security or data protection implications. Are ADRs often used this way, or should I be looking at something else?

Any advice?


1. I usually advise people to raise an ADR when they are adding new component to a system, a new technology, or really anything that they feel needs context and want to have a discussion about. Usually I advise either making a pr in the repo for that component (this can be in #1 with the first commits of code) or in a centralised docs repo when you are adding new technologies to your stack or setting standards etc. 2. I have used them in place of RFCs at a couple of places. Generally I would write code or docs alongside an ADR and use the comments in a pull request to get a review on it, and try to improve the PR with the comments. If there is a consensus in the PR from enough people it would get merged in, if not i would take it to an appropriate forum to discuss it (guild, standup, meeting etc).

I have found creating a couple of ADRs in a team and getting that team to participate in the process first is a great example to showcase to an organisation at a show and tell, lunch and learn etc. Adr-tools is a great tool to help create an ADR and provides a good template too!


We use Kanban in my organisation and tickets go through a Analysis phase where the dev spells out the technical details of what they're going to do and then an Analysis review where two other devs will validate the analysis. Then the ticket can move to the implementation phase itself.

It may seem a lot of overhead at first but the team is small and tickets go through these two phases fast.

The analysis can be considered sort of an ad-hoc ADR.

We started this quite recently but it's already useful and did not slow us down.


It's related, but I think it's not quite the same thing. It sounds like you are describing the intended design of the feature you're implementing. As I understand it, an ADR may also set policy regarding future features, where they touch an architectural concern.


I had never heard of ADRs, but now I see that I've been putting some of the information in comments or module-level docs. I'll definitely look into the linked examples!


A community that I've seen doing this pretty well is the Home Assistant community. You might wanna check their examples out.

https://github.com/home-assistant/architecture


I think the fundamental idea behind this is that "every decision must be rationalized", which is fine, but in reality it's difficult to pull off in my opinion. Because people (including myself) are so easily fooled, I'm afraid that it's often the case that we deliberately ignore certain (inconvenient) facts or unconsciously distort things. If we are really trying to rationalize ourselves, the decisions have to be reviewed by multiple people.


It's important to record that a decision was arbitrary, if it was.

For example, my father was in a meeting (snoring, as was his right as the longest serving member of the organization) when he overheard someone say, "We shouldn't change that, it's probably done that way for an important reason." Luckily, he woke up and interjected, "No, I picked that arbitrarily 30 years ago. Go ahead and change it." It'd have been better if he had written down the rationale, but don't judge. He wrote down plenty over the years.


Not sure about that. Writing software requires heavy rationalization just to get a minimally working system. This is one reason some people aren't cut out to be programmers—they just don't have to patience to deal with the pedantic requirements of implementing cold, hard, unambiguous system logic.

I think it's more about documentation of that rationalization, and I wouldn't want to raise the bar on this by requiring a review. The value of every engineer just braindumping the roughest cut of their thinking already provides a tremendous amount of value over the history of a long-lived code base. Personally I do this in commit messages even for solo projects, but for larger teams/code bases/SOAs a more formal document-based approach allowing for diagrams and additional metadata is highly valuable if done consistently.


Rationalization or reasoning? I'm not sure which you're talking about, and the meaning of your text winds up being pretty different in each case. I'm not sure I disagree with either.


I don't think that is the fundamental idea... I think it is more about recording the decision making process rather than making sure it is rational.

The point is that, in the future, you can look at the doc to know why a decision was made.

You can then use that info when you are faced with deciding to make changes; maybe the circumstances changed and you now want to make a different decision. Or, maybe there are reasons that were forgotten, and you really should keep the system as it is.

You might read the ADR and realize the reasons were arbitrary and there wasn't a particularly good reason to choose what they did... that is good info to have!

I feel like this is a way to avoid a Chesterton Fence situation.

https://en.wikipedia.org/wiki/Wikipedia:Chesterton%27s_fence


I would agree that ADRs are not really necessary if you work alone. Maybe not even within a team if it stable over a long time.

Where ADRs are helpful is when many teams cooperate and if people come and go. The reviews happen implicitly because the decision is discussed among many people.


I'm not sure. I work in a small stable team and I had to do a tech due diligence report... it's really amazing being able to go two years into the past and pull the exact reasons why certain design decisions were made.

Not all our designs and decisions panned out ofc, but just having the articles already helped a ton getting through that DD and it really helps give new starts a much better feeling for the code base and where it came from


The basic idea is good, but isn’t a commit message the best place for this? That will ensure that people will find it when looking through source control history to understand some code, but equally importantly, they won’t find it on its own and be unsure whether it’s still relevant.

When it’s part of the git history, the history itself tells you whether those changes stuck around or were superseded.

Checking the original post to make sure I’m not just repeating it, I don’t think I am -- it links to https://github.com/joelparkerhenderson/architecture_decision... which proposes a whole bunch of acronyms (ADL, ADR, AKS, ASR) but doesn’t offer an opinion on where they should be stored! This is bureaucracy for bureaucracy’s sake, missing the wood for the trees.

Edit to add: I’m not quite right, it does offer an opinion; it suggests text files in an “adr” directory. For the reasons outlined above I think this is both more and less than you need. (Maybe there should be an ADR for the location of the ADR directory...?)

TL;DR: we don’t need a whole new set of complex workflows for this, we just need good commit messages.


I'm the repo maintainer. To answer your questions...

I recommend storing the ADRs as text files in a directory, such as `doc/adr`, or if you prefer words then `documentation/decisions`. Some teams prefer to use a wiki, or CMS, etc. and that can work well too.

I do recommend decision records as separate from git commit messages:

1. Easier for people to create, read, search, manage, sync, and audit. We use simple text formats, such as markdown.

2. Easier to generalize to multiple areas. For example, we use quick decision records to evaluate practices, tools, and techniques, across multiple projects and organizations. Participants don't always have access to the same git repos, and some participants don't even know git (e.g. finance, hard science companies, large enterprises).

3. Easier to update/append/eol when new information arrives. We revisit our decision records, such as when new technologies come into play, or when new requirements are created, or when we grow and want scalability, security, stability, etc. Appending to a text file is a piece of cake.


so what would the experience be for someone new joining the project, particular if you have many repositories? having to search across numerous repositories? In practice I've found this (source control commit messages as ADR's) doesn't work. Unless I have mistaken what you have said? I just keep a repository for ADR's, which can then be published to a wiki or else where.


In that situation, I think the best layout is:

- your centralised wiki lists all the repositories and explains what they’re for;

- each repository has a detailed commit history, allowing you to understand the thinking behind each line of code.

Edit to add: you can search across multiple repos with Github’s “search in organization” feature, and it actually works very well. I usually find that much more useful than searching through a wiki that’s separate from the code (although maybe I just haven’t ever seen a wiki that was sufficiently well organized?)


> each repository has a detailed commit history, allowing you to understand the thinking behind each line of code.

Ch ch ch changes


"Turn and face the strange" describes the git history of more than one project I've worked on...


If you make a habit of browsing your git log with -p or --numstat, you'll see the changes to the ADR show up.

> be unsure whether it’s still relevant.

The idea is that it's still relevant unless it's been marked superceded or deprecated.

> the history itself tells you whether those changes stuck around or were superseded.

Not really. The history has all of the changes, interleaved. So it's not easy for, looking at a commit message way in the past, to know whether a decision described there still applies to some later version.


I came to the same conclusion. I wanted to write ADRs since the first time I read about them a few years back. Thinking more about it I concluded that commit messages are the right place to document this. You can find the commit for a line of code and you can just read git log.

If people tried both and have opinions please share. So far I am ok with commit messages even if they tend to be long.

Another thing. How do you people think ADRs compare to design docs? IMO design docs are for gathering feedback and ADRs are for documenting decided things, there is some overlap.


Most of the changes we (I work in a platform team) make may perhaps only modify a couple of lines of code, but took significant time and effort to reach.

As an example, we recently decided to adopt the use of Kubernetes CPU manager. The actual change was modifying the resource requests for some applications. That part of the code is highly dynamic as apps change and are retuned over time. To store the decision to use CPU manager in a commit message or even a Github PR would not be appropriate -- it's discoverability is too low compared to its importance.

Unlike Git commits or PRs, our ADRs are a rich archive of well thought out decisions with all the rationale that went into making them. We can easily see which ones remain relevant. But what I think is the most important is we have all the information we need to change our decisions and we do. We no longer fear making change because we might not have all the context, or we forgot, or the person who made the decision quit last year.


I don't distinguish between the feedback gathering and the decision record. I collect feedback by integrating it into an ADR draft. Once the decision is made, the ADR is frozen and by construction includes the design documentation.


They could have included some nice examples from GitHub themselves in this blog article.


Wholly agree with you. That's what I'm always hoping for when big company X does a blog post about thing Y, that they actually show some examples about how they have implemented thing Y as otherwise the post falls a bit flat (for me).


When Should I Write an Architecture Decision Record https://engineering.atspotify.com/2020/04/14/when-should-i-w...


yet another name for documentation nobody will write, but the manager will be able to say "solved the lack of documentation this quarter by implementing XYZ".


Thought this was going to be about American Depositary Receipts. Was disappointed... :(




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: