Skip to content

Technical Decision-Making

What this is and who it’s for

This is how a team makes and records technical decisions so they stick, survive staff turnover, and don’t get re-litigated every quarter. It covers what to write down, who gets to decide what, which decisions you make fast versus which you escalate, and how to keep a decision discoverable a year after the person who made it has left. The audience is a tech lead or engineering manager who owns the technical direction of one or more systems. Most teams make decisions in meetings and chat threads that leave no trace, so the same argument resurfaces every few months and nobody can say why the last call was made — this practice replaces that with a lightweight record, a clear owner per decision, and an escalation path you can run yourself.

Prerequisites

  • You have an internal technical owner. Someone must be accountable for technical direction — able to make a call, write it down, and defend it later. Decision-making with no named owner produces decisions nobody owns, which is the same as no decision.
  • You have a repository the team controls. The decision log lives in source control next to the code it governs, so you need a repo the team owns and can write to.

The practice

Write an ADR when a decision is hard to reverse or easy to forget

An Architecture Decision Record (ADR) is a short, dated document that captures one technical decision: the context that forced it, the decision itself, and the consequences you accept by making it. It is not design documentation and not a spec — it’s the answer to “why did we do it this way?” written down once, while the reasons are still fresh. Write one when a decision is expensive to reverse, when reasonable engineers would disagree, or when you’ll have forgotten the reasoning in six months. Don’t write one for routine, reversible choices a single engineer makes inside their own work — that’s noise. The bar is: would a future maintainer who inherits this code waste a day reconstructing why it’s this way? If yes, it’s an ADR.

Keep the format light so the cost of writing one stays below the cost of re-litigating it later. Four parts, no more:

  • Context — the forces in play: the constraint, the problem, what made a decision necessary now.
  • Decision — what you chose, stated as a decision, not a discussion. One clear sentence, then the detail.
  • Consequences — what becomes easier and what becomes harder. Name the trade-offs you’re accepting, including the bad ones.
  • StatusProposed, Accepted, Superseded by ADR-NNN, or Deprecated. This is the field that keeps the log honest over time.

Decide who decides before you decide

The most expensive ambiguity isn’t the decision — it’s who gets to make it. Agree a decision-rights model up front so nobody waits on permission they don’t need and nobody makes a call that wasn’t theirs to make. The three models below are not mutually exclusive; most agencies use all three, matched to the weight of the decision. Pick the lightest one that fits the decision in front of you.

RACI-style ownership for routine, role-bound decisions

Assign each recurring decision type a single accountable owner, plus who must be consulted and who’s merely informed. This is fastest when the decision clearly belongs to one role — the database owner picks the indexing strategy, the platform owner picks the deploy tooling — and you just need everyone to agree that’s their call. The strength is speed and clarity; the weakness is that it only works when ownership is genuinely clear-cut. Use it for the bulk of day-to-day decisions so they never reach a meeting.

A lightweight RFC with a comment period for cross-cutting decisions

When a decision touches several teams or systems, the owner writes a short RFC (request for comments), circulates it, and opens a fixed comment window — three to five working days is typical. Comments are gathered in writing; the owner still decides, but does so having heard objections on the record. This is slower than RACI but produces buy-in and a written trail, which matters when the decision affects people who didn’t make it. Use it when the blast radius crosses team boundaries but doesn’t warrant a full review.

An architecture review for high-impact, hard-to-reverse decisions

For the heaviest decisions — a new core technology, a data model that everything depends on, anything that’s expensive to undo — convene a small standing review group that has to sign off before the decision is Accepted. The group is two or three senior technical people, not a committee; its job is to pressure-test the ADR, not to design by consensus. This is the slowest path, so reserve it for the genuinely irreversible calls. Everything that doesn’t meet that bar should be decided through one of the lighter models above.

Decide reversible calls fast; escalate irreversible ones

Sort every decision by how hard it is to undo, and let that sort decide how much process it gets. The distinction is the single most useful filter for keeping decisions moving without taking on unnecessary risk.

Two-way-door decisions — decide locally and fast

A two-way-door decision is one you can reverse cheaply if it turns out wrong: a library choice you can swap, a folder structure you can refactor, a config you can change. These are the overwhelming majority of decisions, and they should be made fast by whoever owns the area, with no escalation and at most a one-line note in the log. The cost of deliberating over a reversible decision usually exceeds the cost of getting it wrong and fixing it. If you can walk back through the door, walk through it now.

One-way-door decisions — escalate before you commit

A one-way-door decision is expensive or impossible to reverse: a primary datastore, a public API contract other agencies depend on, a data-retention policy, a vendor lock-in. These get an ADR and the heaviest decision-rights model that’s warranted — usually the architecture review. Escalating a one-way-door decision is not bureaucracy; it’s matching the process to the cost of being wrong. The failure mode in both directions is real: escalate everything and nothing ships; escalate nothing and a junior engineer quietly makes a one-way-door call on a Friday afternoon.

Have one escalation path and one tie-breaker

When a decision stalls — owners disagree, or the call is above the owner’s authority — there must be one named person or role it escalates to, known in advance and written down. Don’t improvise the escalation path during the disagreement; that’s when politics replaces judgment. The tie-breaker’s job is to decide, not to re-open the analysis: they hear both positions briefly, make the call, and record it as an ADR with their name on it. A decision that escalates should come back down as a written, dated record within a fixed window — set one (e.g., five working days) so escalation can’t become a place decisions go to die.

TODO: Name your team’s escalation owner / tie-breaker role here.

Keep decisions discoverable in the repo

A decision nobody can find gets remade. Keep the decision log in version control, next to the code, as a folder of numbered Markdown files — docs/decisions/0001-use-postgres.md, 0002-... — so it’s diffed, reviewed, and searchable like everything else. An index file at the top of the folder lists every ADR with its number, title, and current status, so a new engineer can read the index in five minutes and know the shape of the system’s history. Never delete a superseded ADR; mark its status Superseded by ADR-NNN and link forward, so the record of how thinking changed survives. The test is the same bus-factor test from vendor management: if your senior engineer left tomorrow, could the next one reconstruct why the system is the way it is from the log alone?

Decide with vendors, don’t inherit their decisions

When a vendor builds or operates a system, their default is to make the architecture decisions for you — and you’ll discover the choices at acceptance, when they’re one-way doors you can’t walk back through. Require that vendor architecture decisions land as ADRs in the team-owned decision log, reviewed under your decision-rights model before they’re Accepted, not after they’re built. The vendor proposes; your technical owner decides or escalates. The contract and statement of work are where you make this enforceable, so build the decision-rights requirement into the agreement.

Reference implementation

Fork these three artifacts. They are deliberately plain text so you can paste them into a repo, a wiki, or a ticket without tooling. The two templates go in docs/decisions/; the decision-rights table goes wherever your team’s operating docs live.

ADR template

# ADR
| Field | Entry |
| --- | --- |
| Title | - |
| Status (Proposed / Accepted / Superseded / Deprecated) | - |
| Date | - |
| Owner | - |
| Deciders | - |
## Context
## Decision
## Consequences
What becomes easier:
-
What becomes harder / what we accept:
-
## Links
| Field | Entry |
| --- | --- |
| Supersedes | - |
| Superseded by | - |
| Related | - |

RFC template

# RFC
| Field | Entry |
| --- | --- |
| Title | - |
| Owner | - |
| Status | - |
| Comment period | - |
| Decision model (RACI owner / RFC / architecture review) | - |
| Reversibility (two-way door / one-way door) | - |
## Problem
## Proposal
## Alternatives considered
-
## Open questions
-
## Comments (append below; owner does not edit others' comments)
-
## Decision (owner fills in at end of comment period)

Decision-rights table

DECISION-RIGHTS TABLE — <team / system> — Last updated: <YYYY-MM-DD>
| Decision type | Who decides | Who's consulted | Reversible? |
| --- | --- | --- | --- |
| Library / dependency choice | Area owner | Team (informed) | Two-way |
| Internal code/folder structure | Area owner | - | Two-way |
| Service-internal data model | Area owner | Adjacent owners | Two-way-ish |
| Shared / cross-team API contract | Tech lead (RFC) | Consuming teams | One-way |
| Primary datastore choice | Architecture rev. | Tech lead, DBA | One-way |
| Auth / identity approach | Architecture rev. | Security, tech lead | One-way |
| Data-retention / privacy policy | Architecture rev. | Legal, security | One-way |
| Vendor-proposed architecture | Tech lead (review) | Affected owners | Usually one-way |
| Hosting / cloud platform | Architecture rev. | Platform, finance | One-way |
Escalation / tie-breaker for any stalled decision: [FILL IN: named role]
Anything one-way and not listed here -> escalate by default.

Common pitfalls

  • Decisions live in chat and meetings, so they’re re-litigated every quarter. The same argument keeps coming back because the last resolution left no trace anyone can find. Fix it by making the decision log the source of truth: if it isn’t an ADR in the repo, it didn’t happen, and you close re-opened debates by linking the existing ADR.
  • Everything gets escalated, so nothing moves. Reversible, low-stakes calls pile up waiting for a review that doesn’t need to happen, and the team learns to wait for permission. Fix it by classifying decisions two-way versus one-way and pushing every two-way-door call down to the area owner with no ceremony.
  • Nothing gets escalated, so a junior makes a one-way-door call. A cheap-looking decision turns out to be a primary datastore or a public API contract, made fast by someone who couldn’t see the blast radius. Fix it by publishing the decision-rights table so the one-way-door decisions are named in advance and route to review automatically.
  • The vendor makes all the architecture decisions by default. You discover the architecture at acceptance, fully built, with no record of why and no chance to object. Fix it by requiring vendor decisions to land as ADRs in the team log and clear your decision-rights model before they’re built — enforced through the contract and statement of work.
  • ADRs are written once, then abandoned. The log has ten records from the first month and nothing since, so it looks like decisions stopped — they didn’t, they just stopped being written down. Fix it by making “is there an ADR?” a checklist item on any cross-cutting or one-way-door change, and reviewing the log at the cadence in this runbook’s metadata block.
  • No Superseded status, so stale decisions look current. An ADR that’s been overruled still reads as live, and someone builds on a decision you reversed a year ago. Fix it by never deleting an ADR — mark it Superseded by ADR-NNNN, link forward, and keep the chain of reasoning intact.

Decisions precede procurement

Key technical decisions should precede and shape procurement, not follow it. If you buy first and decide the architecture afterward, you’ve handed the most consequential one-way-door decisions to whatever the contract happened to specify. Make the datastore, integration, and ownership decisions — and record them as ADRs — before the statement of work is drafted, so the contract encodes choices you made deliberately rather than ones you inherited.