lockstep
7 min readNaman Jain

The engineering decision log: what to write down, and when

A practical guide to keeping a decision log: one question that tells you what counts, the four fields every entry needs, and the two moments teams always miss.

About a year ago, on a project I work on, someone set a dependency version to latest. It was a deliberate choice, and at the time a defensible one: the SDK was young, it shipped fixes weekly, and pinning it meant chasing releases by hand. The reasoning was sound, spoken aloud, agreed to, and written down nowhere.

A few weeks ago we were onboarding a client, live, when the integration that depended on that SDK went quiet. No error worth the name, just silence. The library had moved four major versions since that line was written, and somewhere along the way the API we called had been retired. The fix took an afternoon: pin a version, update three call sites. The archaeology took longer than the fix. Was latest load-bearing? Did anything depend on the auto-upgrades? Had pinning been considered and rejected for a reason we were about to rediscover the hard way? The person who wrote the line answered from memory, a year stale, with the confidence of someone describing a dream.

The decision log entry that would have saved that afternoon is four lines long. I'll show it to you at the end, after the part that actually matters: how a team decides which calls deserve those four lines.

What Spotify got right

In 2020, Spotify's engineers published an answer to the question every team eventually asks: when should I write an architecture decision record? The post walks through what their teams gained, onboarding that doesn't depend on oral history, ownership handovers that don't lose the plot, alignment across offices, and lands on a flowchart whose punchline is "almost always."

The conclusion has aged well. The flowchart asks four questions to get there, though (do I have a problem, is there a blessed solution, is it documented, is it a big change), and in my experience teams don't fail at decision logging because their test was too loose or too strict. They fail because no test was running at all, and a four-diamond flowchart is a thing you consult, not a thing that runs in your head all day. A habit has to be lighter than the artifact it replaces, which leaves room for exactly one question.

The one-question test

Will this constrain how someone builds later? That is the entire test. The version tag was a yes: every future upgrade, every debugging session, every CI run inherited that choice. Choosing JWT for auth tokens is a yes. A refactor that changes nothing for anyone outside the file is a no, and so is most work, which is what keeps the log short enough to trust.

The reps that teach the test are the borderline calls. A naming convention for API routes: yes, it looks too small to bother with, and then every route ever added inherits it. A workaround for a vendor bug: yes, and it's temporary by nature, so it takes a review date. A chart library for an internal dashboard: only if other people will build dashboards after you. A stricter linter rule: no, the config file is its own documentation. Run a week of work through the question and most of it fails. That's the point.

The filter matters as much as the trigger, because a decision log dies one of two deaths: starvation, where nothing gets written, or obesity, where everything does and the log becomes a place decisions go to be ignored. Teams fear the first death and die of the second. If an entry wouldn't change how someone builds, it isn't a decision. It's a diary.

Two moments deserve special handling, and they are the two that teams miss most.

The first is the backfill, a scenario Spotify's post names precisely. A reviewer pushes back on a pattern and someone replies, "oh, we always do it that way here." An unwritten rule has just surfaced. This is the cheapest moment it will ever have to be written down: everyone's context is loaded, and the disagreement has already located the ambiguity. It only gets more expensive from here, because the next person to trip on it may not have the author in the room.

The second is the explicitly temporary call. "Until the migration lands." "Just for the pilot." Shopify's engineering blog has a decision framework called TOMASP, drawn partly from the Heath brothers' book Decisive, and its final letter stands for the habit that separates good deciders from lucky ones: prepare to be wrong. A temporary decision logged without a review date becomes permanent the moment the sprint ends. The revisit needs an owner and a date, or it never happens, and the temporary thing quietly becomes load-bearing.

Flowchart showing when to log an engineering decision: a real choice that constrains future work gets logged with its verdict, reasoning, rejected alternatives, and owners; temporary calls get a review date; unwritten rules found in review get backfilled
When to log an engineering decision

Yes, a flowchart, in the post that argued against them. This one fits in your head, which is the point.

The four fields of a decision log entry

An entry needs less than people fear and more than they usually write. If you know ADRs, this is that anatomy stripped down to what survives contact with a sprint.

The verdict comes first: one imperative sentence, phrased as a rule someone could follow or break. "Auth tokens are JWT with 15-minute expiry." If it takes a paragraph, it is several decisions wearing a coat, and each one wants its own entry.

Then the why, a sentence or two naming the constraint that forced the choice. This is the field teams skip, and its absence has a specific smell: rules followed as ritual long after the constraint behind them has died, or reversed by accident by someone who never knew the constraint existed. A verdict without its reason can only be obeyed or ignored. It can't be re-evaluated when the world changes, which is the one thing you will eventually need it to do.

Then the rejected alternatives, even as fragments. "Considered sessions in Redis, rejected for operational cost." This field pays out years later, when someone walks up to the same fork and, without the entry, spends a week rediscovering why the other path is a dead end. Teams that skip it re-litigate their own history on a schedule.

Last, a review date whenever the call is temporary, and the names of whoever agreed, because a decision nobody owns is a suggestion. That is the whole discipline: four fields, written in the minute after the call, before the reasoning cools.

One rule for later, too: when a call is reversed, the old entry doesn't get edited. It gets a successor that points back at it. A log you can rewrite is a log you can't trust. You're keeping a history of what governed the work and for how long, not a wiki of the current mood.

Where it lives matters less than when it's read

A folder of markdown files works. A wiki works. What decides whether the log earns its keep is whether entries reach people at the moment they are about to be violated, and I've written before about why that read side is where decision records quietly fail. The pressure on the read side is also rising, because teams now include coding agents that attend no standup and remember nothing between sessions. A person can absorb an unwritten rule from the air of a team over months. An agent reads the log or repeats the mistake at machine speed.

This philosophy is load-bearing in how we built Lockstep: every decision carries its why and its rejected alternatives as first-class fields, temporary ones carry review dates that resurface them when due, and a decision discovered missing at merge time gets prompted for backfill on the spot. The practice needs none of that to start, though. A text file and the one-question reflex are enough.

The four lines

Here is the entry that would have saved our afternoon, in full:

Decision: Track the connector SDK at `latest` (no version pin).
Why: the SDK ships breaking fixes weekly right now; pinning means chasing releases by hand.
Rejected: pinning to a major (upgrade toil we can't afford at this stage).
Review by: 2026-01-05, or when the SDK stabilizes. Agreed: NJ, AR.

One minute of writing, while the reasoning was warm. The library still would have drifted four major versions. The difference is that the review date would have caught it in January, quietly, on our own schedule, instead of a client catching it live in July.

Frequently asked questions

What is an engineering decision log?
A running record of the technical calls that constrain future work. Each entry holds the decision itself, the reason it was made, the alternatives that were rejected, and a review date when the call is meant to be temporary. It can live in a markdown folder, a wiki, or a dedicated tool; the medium matters less than the habit.
What should a decision log entry contain?
Four things: the verdict as one imperative sentence, the constraint or trade-off that forced it, the options that were considered and rejected, and a review date if the decision is temporary. Each missing field has its own failure mode, from cargo-cult rules to dead ends being re-explored.
When should you log a decision?
Whenever a call will constrain how someone builds later. Log it at the moment it is made, backfill it when a reviewer discovers an unwritten convention, and give it a review date when it is explicitly temporary.

Keep reading