Skip to content

Trade-off Framing

Key Points

  • Senior decisions are trade-offs, not "the right answer".
  • ADRs (Architecture Decision Records): short docs; context, decision, consequences. Live with the code.
  • Frame options as comparable: same dimensions across alternatives.
  • "Good / fast / cheap, pick two" template is overused but useful.
  • Write decision in present tense ("we choose X because"); rationale survives.

ADR template

# ADR-N: [decision title]

## Status: Accepted | Proposed | Superseded by ADR-M

## Context

What problem are we solving? What constraints?

## Options considered

### Option A: [name]
- Pros: ...
- Cons: ...

### Option B: ...

### Option C: ...

## Decision

We choose Option B because [rationale].

## Consequences

- Positive: ...
- Negative: ...
- Reversibility: hard / easy. To unwind: ...

## References

- [Linked PRs / docs / discussions]

Live in docs/adr/000N-...md. Numbered. Short (1-3 pages).

Why ADRs

  • Future-self / future-team understands "why this way".
  • Onboarding tool.
  • Avoids re-litigating decisions.
  • Surfaces unstated assumptions.

When to write

  • Technology choice (Postgres vs Cosmos).
  • Architecture pattern (sagas vs workflow engine).
  • Significant migration.
  • Standard / convention adoption.

NOT for: implementation details, trivial choices.

Framing options

Bad:

"We should use Service Bus."

Good:

"We considered: - Service Bus (managed; rich features; cost X). - RabbitMQ (open-source; on-prem; ops cost Y). - Kafka (high-throughput; replay; ops cost Z).

For our 1000 msg/sec workload + Azure infra + business events, Service Bus's DLQ + sessions outweigh the cost. We'd revisit if RPS exceeds 100K (Kafka territory)."

Comparing across dimensions

            | Option A | Option B | Option C
Cost        | $ low    | $$ mid   | $$$ high
Latency p99 | 50ms     | 30ms     | 100ms
Ops effort  | high     | low      | low
Lock-in     | low      | high     | mid
Maturity    | mature   | new      | mature

Apples-to-apples comparison.

"Good / Fast / Cheap"

Pick two. Often deployed too lazily; use as starting point, then refine.

Quality high + Speed high → Cost high.
Cost low + Speed high → Quality low.
Quality high + Cost low → Speed low.

For real decisions, more dimensions matter (lock-in, ops, team familiarity).

Decision triggers

Document why a decision is reversible:

Decision: use Postgres.
If we hit X RPS or Y data size, revisit (Cosmos for global; Spanner for scale).

Sets future self up for principled re-evaluation.

RFC vs ADR

Doc type When
RFC: proposal for discussion Pre-decision
ADR: decision recorded Post-decision

RFCs become ADRs. RFCs invite changes; ADRs document settled.

Writing under pressure

  • One paragraph context.
  • Three options bullets.
  • One sentence decision + reason.
  • Three consequence bullets.

That's a 1-page ADR. Better than no ADR.

Common framing mistakes

  • ❌ Single option: "we'll use X" (no comparison).
  • ❌ Vague: "we'll see how it goes".
  • ❌ All-pros, no-cons.
  • ❌ Bias: pre-decided answer dressed as analysis.
  • ❌ Verbosity: 20 pages no one reads.

Tone

Technical writing, not marketing.
Acknowledge cons honestly.
Future you will read this; speak to them.

Communicating decisions

After ADR: - Announce in team channel. - Link from relevant docs. - Reference in code comments where it directly informs ("see ADR-12").

Updating decisions

When a decision changes: - New ADR with status "Supersedes ADR-N". - Old ADR updated to "Superseded by ADR-M". - Don't delete history.

In code reviews

When questioned: "Why this approach?" - Reply: "See ADR-7" or "Worth a new ADR; let me write one." - Reduces re-debate.

Senior considerations

  • Decisions worth recording: anything someone could reasonably re-question in 6 months.
  • Brevity wins: short ADRs read; long ones don't.
  • Acknowledge uncertainty: "we're uncertain about X; revisit when Y".
  • Build the muscle: write an ADR when you'd otherwise have a long Slack thread.

Cross-references