35. Enterprise Decision Framework
Enterprise Decision Framework
TL;DR
- No architecture option is “better” in every dimension — every real decision is a trade-off against a specific set of constraints.
- Build vs. buy hinges on one question: is this component genuinely core to product differentiation, or undifferentiated heavy lifting a managed service already solves?
- Cost vs. performance can’t be resolved without an explicit business requirement — “cheaper” and “faster” are meaningless without knowing what the workload actually needs.
- A risk analysis without likelihood, impact, and an assigned owner per risk is not a risk analysis — it’s an unprioritized, untracked list.
- Architecture Decision Records (ADRs) must capture rejected alternatives and rationale, not just the final decision — otherwise the decision becomes unauditable and unquestionable once its author leaves.
Core Concepts
Trade-off analysis
Every real architecture decision trades one dimension for another; there is no option that is simply “better” in all respects. A design review that presents one option as obviously correct without naming what it costs is either dealing with a genuinely simple case (rare at the scale where these decisions matter) or has failed to surface the actual trade-off. Making the trade-off explicit — what does this option cost, what does it save, on which axis — is the substance of the decision, not a formality around it.
Build vs. buy
The recurring question: is this component genuinely core to what differentiates the product, or is it undifferentiated heavy lifting a managed service already solves well? Building a custom queue when SQS solves the problem, or custom authentication when Cognito or a managed IdP solves the problem, trades engineering time that could go toward actual differentiation for an ongoing maintenance burden with little strategic value. The reverse case matters equally: a “buy” option can genuinely fail to fit a specific, differentiated requirement, in which case building custom is correct. The failure mode is defaulting to one answer without asking the question explicitly each time.
Cost vs. performance
Cost and performance are a genuine trade-off, not a comparison where the cheaper option automatically wins. “20% cheaper” versus “30% better p99 latency” cannot be resolved without an explicit business requirement: is the latency improvement worth the cost for this workload’s actual user experience needs? A checkout flow and an internal reporting dashboard have very different answers to that question. Picking based on cost alone, without first naming what the workload requires, skips the actual decision.
Risk analysis
A risk analysis that lists risks without likelihood, impact, and an owner is a list of things that could go wrong — unprioritized and untracked, functionally equivalent to not having done the analysis. A risk register with dozens of entries and no ranking gives no way to tell which risks actually matter. A risk with no assigned owner remains open and unaddressed indefinitely, surfacing unchanged at every subsequent review.
Service selection
Service selection should follow from trade-offs already made explicit, not precede them. Picking a specific AWS service before the requirement, constraint, and trade-off have been named is choosing an implementation before the problem has been defined.
Architecture Decision Records (ADRs)
An ADR is the artifact that makes a decision durable and reviewable later. A complete ADR captures: the context (the actual constraint driving the decision), the options considered (including rejected ones, and why they were rejected), the decision itself, and its consequences. Documenting only the conclusion — without rejected alternatives and reasoning — leaves a load-bearing decision unauditable once the original decision-maker is unavailable: the team is left to either blindly preserve the decision or blindly reverse it, with no way to evaluate whether it still holds.
Build vs Buy
| Aspect | Build | Buy (managed service) |
|---|---|---|
| Best suited for | Components that are genuinely core to product differentiation | Undifferentiated heavy lifting already solved by a mature managed offering |
| Cost profile | Upfront and ongoing engineering time; full control over trade-offs | Lower upfront cost; recurring service cost; less control over edge-case behavior |
| Risk if misapplied | Maintenance burden on a problem that adds no strategic value | Custom requirement doesn’t fit the managed service’s constraints, forcing workarounds |
| Long-term burden | Team owns scaling, patching, and operating it indefinitely | Provider owns operational burden; team owns integration and migration risk |
Common Pitfalls
- Pitfall: Load-bearing architecture decisions with no documented rationale. Why: Context and reasoning exist only in the original decision-maker’s memory. Fix: Require an ADR for load-bearing decisions before they ship.
- Pitfall: Defaulting to “build” for undifferentiated infrastructure a managed service already solves. Why: The build-vs-buy question was never asked explicitly. Fix: Evaluate whether the component is genuinely differentiating before choosing to build.
- Pitfall: Cost-vs-performance decisions made by picking the cheaper option by default. Why: No explicit business requirement was established before comparing options. Fix: Define the workload’s actual latency/UX requirement first, then evaluate cost against it.
- Pitfall: Risk registers listing risks with no likelihood, impact, or owner. Why: An unranked, unowned list can’t be prioritized or tracked to resolution. Fix: Require likelihood, impact, and an owner for every entry in a risk register.
- Pitfall: ADRs that document only the final decision. Why: Rejected alternatives and their reasoning are lost, so the decision can’t be re-evaluated later. Fix: Require ADRs to include rejected options and why each was rejected, not just the conclusion.
Interview Questions
- “Walk me through a decision where you’d choose ‘build’ over ‘buy,’ and defend why that’s the right call for that situation.” — tests whether the candidate applies judgment per situation rather than a blanket default.
- “You inherit an architecture decision with no documentation and no one left who made it. How do you evaluate whether to keep it or change it?” — tests how they reconstruct missing context and whether they understand why ADRs exist.
- “Present a cost-vs-performance trade-off for a specific workload, and defend which side you’d choose and why.” — tests whether they can reason about a concrete trade-off tied to a real requirement.
- “What’s wrong with a risk register that lists twenty risks with no likelihood or impact ratings?” — tests understanding of what makes a risk analysis actionable versus decorative.