What a Decision Log Is, and a Template That Lasts
Table of contents
A new engineer wants to delete the retry setting. It is weird, it is undocumented, and it looks like someone pasted it in during an incident and never cleaned it up. You have a feeling there was a reason, so you go looking. The pull request that added it is closed and says "fix flaky job." The Slack thread where it was argued out scrolled into the archive months ago. The calendar event for the meeting has no notes. The setting is still running in production, still doing its job, and the reasoning behind it has completely evaporated.
That is the gap a decision log fills. Not the choice itself, which the code already records, but the "why" around it: what forced the call, what else you considered, and what you were betting would stay true. The pull request captures what changed. The decision log captures why anyone agreed to it, which is the part that goes missing exactly when someone needs it to decide whether the decision still holds.
What is a decision log?
A decision log is a single, append-only record of the meaningful choices a team or a project makes, each entry capturing the decision, the context that forced it, the options considered, and the reasoning behind the one that won. It is a running list, not a per-file document: one place you can scroll back through to see what was decided, when, by whom, and on what assumptions. The point is to make the reasoning available to people who were not in the room, including your future self, after the memory of the discussion is gone.
It earns its keep in the moment the retry setting earns a second look. Without the log, a decision that is questioned later has to be reconstructed from memory or reopened from scratch, and both are expensive. With it, the answer to "why is this here?" is one entry away, and the follow-up question, "does that reason still apply?", becomes answerable instead of a shrug.
What belongs in a decision log entry
Most of the value in a decision log is in two fields people are tempted to skip: the options you rejected, and the assumptions the choice depends on. The decision and the date are easy and nearly useless on their own. A bare "we chose Postgres, 2026-10-14" tells a future reader nothing about whether to trust it. The rejected options tell them what was already weighed so they do not re-litigate it, and the assumptions tell them the exact conditions under which the decision stops being correct.
A workable entry has six fields:
- Decision: the choice, in one sentence.
- Date and owner: when it was made, and who made or approved it.
- Context: what forced the choice now, not the whole backstory.
- Options considered: including the ones you rejected, and the reason each lost.
- Assumptions: the facts this decision depends on being true.
- Status: active, or superseded by a later entry (with a link to it).
That last field is what turns a list of decisions into a log you can trust. A decision is a bet on its assumptions, and bets get called. When a later choice reverses an earlier one, you do not delete the old entry; you mark it superseded and point at the entry that replaced it, so the history of "why we changed our mind" stays legible. This is the same supersession discipline that a well-maintained architecture decision record uses, borrowed down to a lighter weight.
A decision log template you can copy
You do not need a spreadsheet or a tool for this. A decision log is text, and the most durable form is a markdown table or a list of short entries kept wherever your team already writes. The ranking template results for this term are Excel and Word galleries, which is fine for a project manager tracking approvals, but a log that lives in a .xlsx on someone's drive is a log nobody reads. Keep it in plain text, next to the work.
Here is a table form for a project or a team:
| Date | Decision | Context | Options (rejected -> why) | Assumptions | Owner | Status |
|------|----------|---------|---------------------------|-------------|-------|--------|
| 2026-10-14 | Use Postgres for the billing service | Needed a store before launch; team knows relational | DynamoDB (nobody has run it in prod); SQLite (no concurrent writes) | Write volume stays under ~500/s this year | A. Okafor | Active |And here is a longer per-entry form when a single table cell is too cramped for the reasoning:
2026-10-14 | Use Postgres for the billing service
- **Context**: We need a datastore before the launch date, and the team
already runs Postgres for two other services.
- **Options**: DynamoDB (rejected: no one here has operated it in
production, and billing is a bad place to learn); SQLite (rejected:
concurrent writes from the workers).
- **Assumptions**: write volume stays under ~500/s this year; we stay on
a single region.
- **Owner**: A. Okafor. **Status**: Active.Pick one shape and keep every entry in it. Consistency is what lets you scan the log in a year without re-reading each entry in full, and it is the thing a spreadsheet template quietly gives up the moment two people fill it in differently.
A worked example: one decision, then superseding it
Say the Postgres entry above is a year old now. The service grew, write volume blew past the assumption, and the team has moved the hot path to a queue with a separate store. The wrong move is to edit the old entry to say "we use a queue now," because that erases the fact that the original call was reasonable on the information it had. The right move is a new entry that supersedes it:
2027-02-02 | Move billing writes to a Kafka + Postgres split
- **Context**: Write volume hit ~2,000/s, past the 500/s the 2026-10-14
decision assumed. Latency on the synchronous path became the incident.
- **Options**: Shard Postgres (rejected: operational load for a team of
three); managed DynamoDB (reconsidered and chosen this time, for the
write path only).
- **Assumptions**: read-heavy reporting stays on Postgres.
- **Owner**: A. Okafor. **Status**: Active.
- **Supersedes**: 2026-10-14 (Use Postgres for the billing service).Then you go back to the October entry and change its status to Superseded by 2027-02-02, and nothing else. Read top to bottom, the log now tells a true story: a sound decision, the assumption that expired, and the decision that replaced it. That narrative is worth more than either entry alone, because it is how a team learns that its real failure was not the database choice but not writing down the assumption so anyone would notice when it broke.
Decision log vs ADR vs decision framework
Three practices sit near each other and get confused, and reaching for the wrong one is why teams either over-document small calls or under-document big ones. A decision log is the running list. An architecture decision record is the formal, per-decision document for architecturally significant choices, kept in the repository next to the code and never edited after acceptance. A decision-making framework is the process you run to reach the choice in the first place, before there is anything to log.
| Decision log | Architecture decision record (ADR) | Decision-making framework | |
|---|---|---|---|
| What it is | A running list of decisions and their reasoning | One formal document per architectural decision | A process for making the choice (RAPID, WRAP, a decision matrix) |
| Scope | Any team or project decision | Architecturally significant choices only | The decision you are making right now |
| Lives | A wiki page, a notes doc, a DECISIONS.md | docs/adr/ in the repo, one file per ADR | In the meeting or the moment of choosing |
| When to reach for it | You want one place to see every decision | A structural choice future engineers must not quietly undo | You are stuck on how to decide, not on recording it |
| Granularity | One row or short entry each | A page each, with consequences and alternatives | Not a record at all |
The clean rule: use a framework to make the call, write it to the decision log so the reasoning survives, and promote the heavyweight structural ones into ADRs. The Microsoft engineering playbook keeps exactly this split, treating the decision log as the lightweight design-review artifact and ADRs as the formal ones. Most teams need the log far more often than the ADR, because most decisions that get questioned later were never "architectural" enough for anyone to feel they warranted a document.
Where to keep a decision log so it survives
A decision log is only as good as your odds of finding it when you need it, and those odds are decided by where it lives. Three options, in rough order of how well they hold up:
A DECISIONS.md in the repository is the strongest for engineering decisions, for the same reason an ADR works kept next to the code: it is version-controlled, it travels with the project, and it shows up in the diff when someone touches the thing the decision was about. A team wiki page works for cross-functional calls that are not tied to one codebase, as long as someone owns keeping it from sprawling. A log in your notes app is often where it actually happens, because the reasoning gets captured at the moment of the decision instead of reconstructed at review time, and a running work log you already keep is a lower-friction home than a file you have to remember to open.
The deeper benefit of a plain-text log, wherever it lives, is that it stays readable by the tools you will use to search it later. A decision logged as text is something an AI assistant can read back when you ask "why did we choose Postgres for billing?", and answer with the actual entry and its assumptions, instead of you scrolling an archive. A decision trapped in a spreadsheet cell or a closed ticket is not. The whole value of the log is retrieval, and plain text keeps it retrievable.
Why decision logs rot, and how to keep one honest
The failure mode of a decision log is not that people stop writing it. It is that the entries keep standing after their assumptions have moved, and a written decision that has quietly gone stale is more dangerous than one you never recorded, because a confident, outdated record gets trusted. People cite it, build on it, and defend it long after the reasoning underneath stopped being true. This is the half-life that sits under every written artifact: nobody edits a decision to make it wrong, it goes wrong by standing still while the world moves.
The fix is built into the fields above. The Assumptions field names the conditions that have to hold, and the Status field is where their expiry gets recorded. A log kept this way is not just a record of what you decided; it is a list of bets with their terms attached, which is the only form of decision record that can tell you when to re-check it. The habit that makes it pay off is a periodic read, the decision journal Shane Parrish popularized, where you go back over old entries against what actually happened and grade your own calls. That review is also the cheapest insurance against a bus factor of one: when the person who made a decision leaves, the log is the difference between the reasoning walking out the door and staying on the page.
This is the problem Scribelet is built around. A decision log should not be a file you trust and forget; it should be a set of notes that reads its own assumptions and tells you which of your team's decisions have quietly gone out of date since anyone last looked, and answers "why did we decide this?" when you ask. You can try it free and keep the reasoning behind your decisions somewhere it gets re-checked instead of merely believed.
Start the log before you need it. The entry you will wish you had is the one for the weird retry setting, written on the day it stopped being obvious and kept somewhere the next engineer can find it before they reach for the delete key.
Share this article