A practical overview on Architecture Decision Records (ADR)

How to start and why this could be your most valuable action as a software architect

I have been using ADRs for some years.
In this article I’ll try to give an introduction, share my feedback, and encourage you to start writing them if you already don’t.

A little about the architecture decisional process

Taking architectural decisions is tough.
It can be the result of a bunch of technical and non-technical evaluations, made of tricky balances between technology, cost, time, and stakeholders’ requests.
There is rarely one single, optimal solution. Instead, there are many reasonable solutions, no true/false, only better/worse options.
The final decision may seem like a small thing, but a lot of work may have been required to come to that decision.
For this reason, architectural decisions are usually considered “wicked problems”.

Nevertheless, most teams come to a decision verbally during meetings, and those decisions are sooner or later lost or forgotten. And all that remains is just the state of things.

This is a shame because, in a nutshell, the real value of a decision is what is stated by the “Second Law of Software Architecture”:

Why is more important than how.

If you are curious about the first law, I’d wholeheartedly recommend that you get and read the great book Fundamentals of Software Architecture written by Mark Richards & Neal Ford.

Before going deep into considerations and tips, it’s useful to clarify the discussion by giving a quick definition:

An ADR is simply a concise document that explains
why something is going to be made this way
.

The structure of an ADR

This is a basic example of an ADR template, in markdown format, as suggested by Michael Nygard.

# Title

## Date

## Status
What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.?

## Context
What is the issue that we're seeing that is motivating this decision or change?

## Decision
What is the change that we're proposing and/or doing?

## Consequences
What becomes easier or more difficult to do because of this change?

There are a lot of other templates, with different levels of complexity, but in my opinion it is better to keep it short and easy. And Nygard’s template is perfect, according to me.

If you want to see some real examples, you will find at the end of the article some links to pages with many detailed resources and examples.

Every decision should have a unique code, usually in the filename and in the title, resulting in something like:
ADR0001 - Use an SQS queue to manage outgoing emails

Every ADR should explain one single decision, not many of them.
It’s frequent to write multiple ADRs after a long analysis, but each one should have its own code and its own lifecycle, because in the future some of them will change status, while others will stay in accepted state.

WHY are ADRs important?

Now that we know what’s an ADR, it’s important to understand in-depth the advantages of the adoption of this framework.

Tracking the knowledge

Architecture decisions are pieces of knowledge, among the most important, in my opinion.
People move between teams and companies, and it’s important not to lose that knowledge when someone leaves the team.
On the other side, when a new member joins the team, they will face exactly the same lack of knowledge, and for sure they will ask themselves: “Why the hell was the system designed in this way?”.
We developers are opinionated guys, and an architecture decisions log can be a great way to share knowledge and prevent frustrations.
When given to new team members it can be a really powerful document, whose reading can save days, during the onboarding process.

Empowering the team culture

Writing down architectural decisions is the first fundamental step to making them first-class entities in the teamwork final result.
It’s the most structured way to align officially the whole team about the work behind important decisions.
If the team is big, it can reduce the distance between design and development. In this way, everybody can understand decisions that otherwise, from the bottom, without an overall view, could seem incomprehensible. Tracking decisions is also something that contributes positively to the team culture, because between the lines it says “For this team, the design counts”.

A matter of responsibility

As a software architect, or as a technical leader, or even as a team with shared leadership, one of your most important responsibilities is taking these decisions. Not writing them down could dangerously suggest that things are happening without a reason, driven by pure instinct, or worse randomly.

Your decisions could have an impact for many years, even if you will leave the project. It’s a matter of professionalism, seriousness, and respect for those who end up with the system in the future.
Also, in the future, the ability to go back to old decisions and understand why they were taken, has many advantages, which include:

  • You will have the possibility to remember details that you will undoubtedly have forgotten.
  • If the decision, seen from the new context, will still appear as a good decision, good news for your self-esteem. You have been forward-looking or at least you’re a lucky person.
  • If it will seem a bad decision, well, you will have the possibility to go deep into it, and you will be able to make a valuable retrospective and understand what happened:
    • Option 1: The context was completely different, and now you can say that in that context it was the best option, or at least a good one. You did your job well. You are a software engineer, not a fortune-teller.
    • Option 2: The context is pretty much the same, but you are now able to consider other variables, that you missed in the past, and that change your point of view. You are growing, you have improved your judgment, and your next decision will be more accurate.
    • Option 3: The context is exactly the same, and at this point, it’s official what was already clear to everybody: you made a mistake. Anyway, it was a difficult decision, and at least you have a document that shows that you did your best, you’re not just a fool. Learning from your mistake, you’re already a better professional now.

Other indirect advantages

Usually inside an ADR are also documented, in a more or less detailed fashion, the findings from investigations explored but not implemented. Describing the option that you are identifying as the best one, it’s almost inevitable to explain also why the other options are not so good.
This information can have a huge value in the future, but is frequently lost, because there are no evident and direct reasons to track a solution that seems inappropriate.

Another last-but-not-least advantage is that writing down an important decision is a way to force ourselves to be objective and wise.
No one would ever write something like “We do this because we want to play with that sexy technology”, but this is something that happens often. If you are a developer you know that it’s true.

Is just-plain-text mandatory?

In this field there are no absolute laws.
If a decision involves a complex relationship that could easily be described with a diagram, I think that it’s okay to add it.
Anyway, this should be only considered as an option if strictly necessary to avoid confusion, because in most cases it’s not needed.
It’s likely, on the contrary, that if you feel the need for a diagram there is something wrong. It’s a wake-up call that you are mixing more decisions into one.

The lifecycle of an ADR

Every decision should start from a draft version, usually in proposed status, then move to accepted or rejected, and so on.

The document should be managed with an append-only approach. Of course, you can edit any part of the decision to fix a typo, but the only part of the document that should evolve is the STATUS paragraph.
If the decision is no more relevant, it should simply change its status to deprecated. If the context changes, a new ADR should be created, and the old one should move to status superseded, and so on.

In my experience, it’s useful to add cross-links between ADRs. I’m used to creating links both when the relation is direct (for example “Superseded by ADR0027”) and when there is simply some kind of relation between two decisions (for example the second one is a consequence of the first one).
If you’ve ever used Jira or a similar issue-tracking tool you probably get my the point.

WHERE should ADRs be stored?

I think that there is no right answer, it depends on the team culture.
The most common solutions are:

  • a wiki platform
  • a git repository

I think that there are pros and cons for each solution. By the way, this decision could be a good candidate as a subject for the first ADR… ;-)

Store into a wiki

If you think that ADRs should be easily accessible to everyone in your team, including non-technical people, this is for sure the best option. In addition to that, having them in the wiki is good because it’s easier to link the ADR from other project documentation pages, without leaving the platform.
In my opinion, this advantage is also a drawback, because it puts the architectural decision in the field of “documentation”, which is not exactly the passion of each developer.

Store in a git repository

If you want the developers to perceive ADRs as something important, using git is for sure a good starting point. Developers love code and love git, and in their mind, the subliminal message is “if it goes into a repo, it’s important”. Git is a great tool also to enable collaborative management of the release process of a new ADR, leveraging pull requests for decisions in proposed state.
There are some good command line tools that could work well to automate the process. I still haven’t tried them, because for the time being I have not felt the need, but it could be an interesting option in the future.

There is also an interesting win-win tool called log4brains, that can turn your markdown into a static website. It’s also integrated into MADR template.
I haven’t had time to try them yet, but it could be something to look into in the future.

WHO should be in charge of tracking ADRs?

It doesn’t matter.
This simply depends on the team and its culture. It could be a software architect, an entire team, a single developer, an ivory-tower architect, a technical leader, a senior developer or anyone else.
Just to be clear, this is a very important issue, but from this perspective is irrelevant. What really matters is rather WHEN.

WHEN should an ADR be created?

  • When the decision will affect the work of the developers
  • When the decision will be hardly reversible
  • When the decision is not obvious to the entire team
    (but pay attention, the team will change, sooner or later)

Some final tips

While compiling the ADR, be very detailed about the context.
This is the part that in the future might differ more, so it’s important not to be vague and not to assume anything. Describe the context with just facts, not opinions.

Take your time thinking about the consequences, because it’s at that moment when the deepest reflections will come to light.
And maybe you could even completely reconsider a decision that just a few minutes before seemed so good.

References

TLDR

If you are responsible for architecture decisions and already don’t, start documenting them. Now.
It’s fast, easy, not time-consuming, and there are tons of good reasons.

Share: Twitter Facebook LinkedIn