Write an architecture decision that explains the tradeoff

An architecture decision is difficult to evaluate when it starts with a preferred technology and ends with a list of its features. The reader still does not know what problem required the choice, which alternatives could have worked, or what cost the team accepted. Months later, someone repeats the discussion because the reasoning was never recorded. A useful decision record preserves enough context to judge the choice without recreating the meeting.
Consider an illustrative document export feature. Users want downloadable reports, export work can outlast a normal request, and failures must be visible. The team is choosing between generating reports during the request and scheduling durable background work. No measured production workload is assumed here. The decision must say which facts are known and which remain estimates.
State the concrete trigger
Begin with the behavior that makes a decision necessary. For exports, a large report may exceed the request time budget, and a disconnected browser must not be the only owner of the work. State the user-facing requirement: an accepted export should either become downloadable or reach a visible failure state. This gives reviewers a standard against which to compare alternatives.
Separate facts from assumptions. A configured request timeout is a fact that can be checked. Expected report size is an estimate until representative data has been measured. A requirement for completion within a particular period needs a product owner or service agreement behind it. Avoid presenting desired scale as an existing constraint. This distinction prevents speculative requirements from becoming permanent infrastructure without anyone noticing the jump.
Identify realistic alternatives
Include alternatives that the current team could implement. Synchronous generation may remain acceptable for bounded exports. A database-backed job table may be sufficient when there is already a worker and modest scheduling needs. An external queue may help when concurrency, retry management, or independent consumers justify it. Describe how each option meets or fails the required outcome.
Do not create a weak alternative merely to make the preferred option win. If a job table solves the immediate problem, acknowledge that. If operating workers is beyond the team's current capacity, include the cost of learning and supporting them. The record should compare responsibility for retries, observability, duplicate execution, and cleanup, not only the number of code files. Link more detailed experiments separately so the decision remains readable.
Record the choice and accepted costs
Write the decision in direct language. For example: export requests will persist a job and return its identifier; a bounded worker will generate the artifact; the UI will read job status. State the important contract without turning the record into an implementation manual. Include the allowed states and who can access the resulting file.
Then list consequences honestly. The request becomes faster to acknowledge, but completion becomes asynchronous. The worker needs monitoring, retry policy, and concurrency limits. The artifact needs retention and permission checks. These are accepted costs of meeting the requirement. If the design does not guarantee exactly one execution, say so and explain which operation must tolerate repetition. A record that contains only benefits is a proposal brochure, not a decision a future maintainer can use.
Use a compact reviewable artifact
A practical record can contain a title, status, date, context, options, decision, consequences, and review trigger. Status distinguishes a proposal from an accepted choice and an older superseded decision. Use a stable identifier so related pull requests can refer to it. Keep the record in the repository if that is where engineering decisions are reviewed.
For the export example, add a small acceptance list: rejected requests create no job; accepted requests expose a status endpoint; retries cannot overwrite another user's artifact; expired artifacts return a clear unavailable outcome. This turns the reasoning into behavior reviewers can follow. The artifact does not need a lengthy history of conversations. Preserve disagreement only when it explains an unresolved tradeoff or a risk that the implementation must manage.
Define when to revisit it
A decision should not require an annual debate to remain legitimate. Name the conditions that would make the current choice insufficient. An export backlog that repeatedly violates the agreed completion objective, a new requirement for scheduled reports, or several independent consumers could justify reconsidering a job table. These are meaningful triggers because they change the problem.
Avoid vague phrases such as revisit when scale increases. Explain which metric, capability, or ownership change matters. Also name evidence that would support retaining the design. If the worker stays within resource limits and recovery is reliable, a more elaborate queue may add little. Review triggers make the architecture adaptable while preventing constant churn whenever someone discovers a new service or an AI assistant recommends a different stack.
Verify the decision against implementation
At review time, compare the record with the delivered behavior. Check that job creation is durable before the server acknowledges acceptance. Check that an export cannot be downloaded by a different account. Check that worker failure produces a visible state instead of an eternally spinning screen. These checks validate the chosen contract rather than the format of the record.
Record experiments accurately. If a local test used a small synthetic dataset, do not describe it as a production capacity test. If an external queue was not evaluated, say that its suitability is based on documentation and design analysis. Link relevant evidence and limitations. For background execution details, see designing durable background jobs. A decision record is strongest when its claims can be traced to implementation or explicit requirements.
Avoid freezing accidental details
Record choices that affect future work, risk, or ownership. A variable name and a temporary helper generally do not need architecture decisions. A persistent message contract, data ownership boundary, or compatibility strategy does. Too many records make important decisions difficult to find; too few leave future maintainers guessing.
Do not edit an accepted record until it looks as if the new choice was always intended. Mark it superseded and connect the replacement, preserving the earlier context. Correct factual mistakes openly when necessary. The point is not bureaucratic immutability but a useful explanation of how the system reached its present design. Keep operational procedures elsewhere so changing a deployment command does not make the architecture rationale stale.
Use AI as a skeptical editor
Give an assistant the draft and relevant requirements. Ask which statements are facts, assumptions, or decisions; which alternative has been dismissed without evidence; and which consequence lacks an owner. This review is more valuable than asking the model to write an authoritative essay about the selected technology.
Ask it to propose concrete review triggers and failure cases, then inspect those suggestions with the team. Do not let it invent measurements, regulatory obligations, or operational experience. A useful final prompt asks for a shorter version that preserves the actual tradeoff and unknowns. Human reviewers still decide what costs are acceptable. AI can improve clarity and expose gaps, but it cannot make an unmeasured constraint true by expressing it confidently.
Sources
Michael Nygard's original architecture decision article introduces the lightweight record approach.
AWS's transactional outbox pattern is useful when a proposed asynchronous design must coordinate a database commit and message delivery. The export alternatives above are illustrative.
About the Author

Kamruz
Full Stack Developer
A passionate developer who loves creating modern web applications and sharing knowledge with the community.
More About Me