Build vs Buy: ROI and TCO Analysis
Concept
"Build vs buy" decisions — write custom auth vs use Clerk/Auth0, self-host Postgres vs use a managed DB, build an internal admin tool vs buy one — are routinely made on gut feeling ("we can build this in a sprint") because the honest cost comparison is more work than the decision itself feels worth. Total Cost of Ownership (TCO) and Return on Investment (ROI) are the two numbers that make the comparison explicit instead of implicit.
TCO is the full cost of a path over its useful life, not just the sticker price. For a build, that's engineering time to build it (often the only cost anyone estimates), plus the recurring cost everyone underestimates: ongoing maintenance, on-call burden when it breaks, security patching, and the opportunity cost of the engineers who now own it instead of building product features. For a buy, TCO is vendor subscription cost plus integration engineering time plus the switching/lock-in cost of leaving later. AWS's TCO framing for cloud-vs-on-prem decisions generalizes directly to build-vs-buy: a self-hosted option's sticker price (server cost, or "a few days of engineering time") looks cheap until it's compared against the fully loaded cost of the alternative, including power, staffing, and the opportunity cost of what those people aren't doing instead.
ROI is TCO's counterpart on the value side: what does the built or bought thing actually deliver, and does that value exceed its TCO over a realistic time horizon? A custom auth system might have lower sticker-price TCO than Clerk over year one, but if it takes engineering focus away from the product's actual differentiator, the ROI calculation has to weigh that opportunity cost, not just direct dollars.
Tradeoffs
| Path | Where the cost really lives | When it wins |
|---|---|---|
| Build | Upfront engineering time (often underestimated) + ongoing maintenance/on-call (almost always underestimated) + security ownership | The capability is close to the product's core differentiator, requirements are genuinely unusual, or no vendor fits without heavy workarounds |
| Buy | Recurring subscription cost (scales with usage/seats) + integration time + switching cost if you leave later | The capability is commodity/undifferentiated (auth, payments, email delivery, observability) — a vendor has already amortized the hard engineering across many customers |
| Buy, then build later | Vendor cost while validating the need is real, engineering cost deferred until scale justifies it | Early-stage, uncertain requirements — buying first avoids sinking build cost into a capability that gets thrown away when the product pivots |
The pattern that shows up repeatedly: teams accurately estimate build cost (a sprint, a month), then compare it directly against a vendor's first-year subscription cost — without pricing in that the build's maintenance cost doesn't stop after year one, while the vendor is absorbing that maintenance burden across all their customers. A fair comparison prices both options over the same multi-year horizon, including the maintenance tail.
When to use / when not to
- Use before any build-vs-buy decision on infrastructure-adjacent capability — auth, payments, search, email/SMS delivery, observability tooling — where "just build it" is the instinctive first answer because the initial build looks small.
- Especially valuable when the team is small: the opportunity cost of an engineer maintaining a homegrown system instead of shipping product features is proportionally much larger on a 5-person team than a 500-person one.
- Less useful — or trivially "build" — when the capability is the product's differentiator; buying the thing that makes you unique defeats the point, and no vendor will fit it well anyway.
- Don't run a full TCO exercise for genuinely small, bounded utilities (a one-off script, an internal CLI) — the analysis overhead can exceed the decision's actual stakes; reserve it for decisions with real multi-year cost exposure.
Common pitfall
Comparing build's year-one engineering cost against buy's year-one subscription cost and stopping there. This systematically favors "build" because the build's maintenance burden — the recurring cost of keeping a homegrown auth system patched against new attack vectors, or a homegrown queue surviving new failure modes — doesn't show up in a single-year snapshot. The fix is mechanical: project both paths' costs over the same 2-3 year horizon, include a realistic maintenance-time estimate for the build path (not zero), and only then compare totals.
Engineering Lens
The strongest build-vs-buy answer in a design review isn't "we estimated the build would take two weeks" — it's showing the multi-year TCO comparison, including the maintenance tail nobody wants to admit exists, and stating explicitly what tradeoff was accepted (lock-in risk for lower TCO, or higher TCO for control/differentiation). Teams that skip this step tend to accumulate homegrown infrastructure that nobody budgeted ongoing time for, and it shows up later as unowned tech debt rather than as a decision anyone consciously made.