In Software Engineering, decisions are made more often. These decisions can be as big as deciding the architecture for a new feature or it can be a small decision that needs to be made while working on a feature.

Most of the time the decisions are made and the team continues working on the direction that is decided but the decision is not written for future reference. Or the decision is written either over a user story or on a document repository in the form of architectural diagrams without having the context of why a particular decision was made.

But, what is the problem?

Imagine a scenario when a new team member joins in the middle of the ongoing feature and the person might wonder what is the reason why MongoDB is chosen instead of CosmosDB or why we decided to go for using GraphQL or why we follow Hexagonal Architecture instead of any other architecture.

I would like you to think about another scenario when a tech lead of a team decides to move to another job and then a new tech lead joins. The person might wonder how to continue on a big epic such as converting all applications to have docker support, there might be some user stories that are completed but it would be difficult to find the pattern of which previous tech lead decided to tackle this particular epic and because of what reasons a certain path was chosen.

Okay, so now what?

A simple solution to the above questions is to store the historical decisions in one place called Architectural Decision Records. The abbreviation for the same is ADR so I will use ADR throughout this article to make it easier to understand.

So what are Architectural Decisions? As per Wikipedia, Architectural decisions are design decisions that address architecturally significant requirements; they are perceived as hard to make and/or costly to change. An ADR is a document that captures such decisions.

ADR does not only store the decisions but also stores the context behind taking that particular decision along with the consequences to know what might become difficult or easier to do because of this change.

Now if we go back to the scenario where either a new member joins or a new tech lead joins, there will be a document for each decision that was taken in the past and that will help them to understand while particular decisions were made in the past.

How does RTL use ADRs?

In RTL the proposal was first made between the tech leads of all the teams on whether to start writing ADRs and the outcome was positive which led us to think about the template of the records since we wanted to keep the template simple but precise.

The template

We ended up using the below template for ADRs:

Since most of the fields are described above, I would like you to focus on the Status field which shows the status of the decision that was made in the past. This means we not only store the decisions that were accepted but we also store the decision that was rejected or deprecated as well. This will prevent us from taking the wrong decision in the future.

A small Example

Title
Start using Terraform

Status
Accepted

Context
To be able to standardize the way we create the infrastructure, we want a single approach to do.

Decision
We will be deploying our infrastructure using Terraform. Each team will have its own terraform repository hosted on Azure DevOps.

Consequences
Each team will need to move new services to Terraform deployment and all new infrastructure should be deployed through terraform when possible.

Where to store the decisions?

We had a discussion in past about where to store the decision, it can be either as part of the repository where the code resides or can be on a centralized location like a confluence page. We decided to store the decision records per team in a centralized location which will help to easily check cross-team records and even business people have easy access to such decisions.

How to remind ourselves to write ADRs?

Now we know the benefits of writing ADRs, the template to write one, and also the place where to store but the next question is how to remind ourselves about writing an ADR.

The best place to start thinking about ADRs would be during refinements and while refining a story you may remind each other whether this feature requires a decision to be made for the architecture and if yes then we should also create an ADR for the same. What we generally do in the team is to add a checklist item within the story template as simple as “Does this require creating an ADR?” and this will remind us to think if we really need an ADR or not while refining the story.

On the other hand, an ADR can be written even for the decisions made in the past so that we slowly cover the areas that are not recorded yet and slowly we make it a practice within the team.

Reduces the duplication of efforts

Writing ADRs helps our teams to align with each other and that would remove the duplication of efforts. For example, one team tried and explored the option to use MongoDB for storing sessions over CosmosDB while keeping all other things in mind like efforts, cost, accuracy, etc, and made a conscious decision out of it. When another team comes to an almost similar situation, they can take help from the document written by the other team and hence removes the duplication of efforts.

Final thoughts

It is advisable to write ADRs for all the apparent reasons mentioned above but also try to make ADRs as light as possible and you may avoid making them too complex or too fancy. As long as the document captures the essential points, it should be good enough. This will definitely help in the longer run.