Home/Blog

Build vs Buy Software: A Decision Framework for CTOs

When to build software and when to buy it: a weighted decision matrix, a three-year TCO formula, vendor due diligence checks and an exit plan up front.

Build vs Buy Software: A Decision Framework for CTOs

Buy anything that is not the reason customers choose you, unless no product meets a hard requirement or the vendor's price grows faster than your revenue. Build what differentiates the product and what you must control for compliance or reliability. Decide with a weighted matrix and a three-year total cost of ownership that includes maintenance and on-call, and write the exit plan before you sign.

Key takeaways

  • The first question is differentiation: would a customer notice or care if this were built differently? If not, buy it.
  • The cost of building includes the initial build, years of maintenance, on-call, security patching and the roadmap work that did not happen meanwhile.
  • The cost of buying includes the price at projected scale, integration, workarounds, vendor management and the cost of leaving.
  • Self-hosted open source is a third option with its own bill: upgrades, CVEs, backups and someone on the pager.
  • Wrap every vendor behind an interface you own, so switching costs a sprint rather than a quarter.
  • Record each decision with the conditions that would make you revisit it, so it is not relitigated every quarter.

Start with differentiation

One question settles most build-versus-buy decisions: is this capability part of why customers choose you?

If yes, build it. The quality and pace of iteration on that capability is your competitive position, and a vendor's roadmap will never be yours.

If no, buy it. Authentication, payment processing, email delivery, error tracking and log storage are solved problems with teams of specialists behind them. Your version will be worse and will keep costing you.

Be careful with the word "critical". Payments are critical to revenue but are not what makes most products different, so you buy payment processing and build the pricing logic that is specific to you. A recommendation engine is the product at a media company and a commodity widget at a small e-commerce store. The same capability can be a build at one company and a buy at another.

Quick reference by capability

CapabilityDefaultBuild or self-host when
Authentication, SSO, SCIMBuy, or a mature open-source identity serverIdentity is the product, or residency and control requirements rule out every vendor
Payment processingBuyPractically never; build the pricing and entitlement logic on top
Transactional email and SMS deliveryBuyNever build deliverability infrastructure
Product analyticsBuy or self-host open sourceEvent data cannot leave your infrastructure
Feature flagsEnvironment variables, then buy or open sourceFlags are simple on/off with no targeting
Error tracking and observabilityBuyIngest cost becomes a top budget line; self-host the high-volume part
SearchPostgreSQL full-text, then an open-source engineSearch relevance is part of the product
Internal admin toolsA low-code tool, then buildOps staff live in it all day and the workflow is specific to you
LLM inferenceBuy API accessVolume, latency or data control justify serving open-weight models yourself
Ranking, pricing, matching, domain rulesBuildThis is usually the product

The weighted decision matrix

When the answer is not obvious, score it. Each criterion gets a score from 1 (strongly favors buying) to 5 (strongly favors building). Multiply by the weight, sum, and divide by 100 to get a result between 1 and 5.

CriterionWeight1: favors buy3: neutral5: favors build
Differentiation30Table stakes; no customer would noticeImportant, not uniqueCore to why customers buy
Fit of available products20Several mature products fit as-isProducts fit with notable gapsNothing fits without heavy customization
Three-year TCO15Buying is clearly cheaperComparableBuilding is clearly cheaper at projected scale
Time to value10Needed in weeksNeeded in a quarter or twoCan be built incrementally on the roadmap
Ability to operate it10Needs expertise you lack (crypto, deliverability, payments compliance)Manageable either wayYour team already runs similar systems well
Vendor and lock-in risk15Many interchangeable vendors, easy exitFew vendors, painful exitOne vendor, deep lock-in, or a vendor at risk

Reading the result: below 2.5, buy. Above 3.5, build. Between the two, the decision depends on specifics, and a hybrid (buy now with a revisit trigger, or build the core and buy the rest) is usually right.

Three illustrations

These are illustrative scorings, not case studies. Your inputs will differ, and that is the point of writing them down.

Authentication for a B2B SaaS that will need SSO and SCIM for enterprise customers. Differentiation 1, fit 1, TCO 3, time 1, ability to operate 1, vendor risk 2. Weighted: (30 + 20 + 45 + 10 + 10 + 30) / 100 = 1.45. Buy. Before signing, check which pricing tier includes SSO, SCIM and audit logs, because enterprise deals will need all three.

Transaction categorization at a fintech where categorization accuracy is the product. Differentiation 5, fit 4, TCO 4, time 3, ability to operate 4, vendor risk 4. Weighted: (150 + 80 + 60 + 30 + 40 + 60) / 100 = 4.2. Build.

An internal admin panel for the support team. Differentiation 2, fit 2, TCO 3, time 2, ability to operate 3, vendor risk 3. Weighted: (60 + 40 + 45 + 20 + 30 + 45) / 100 = 2.4. Buy a low-code tool now, and revisit when support workflows outgrow it.

Three-year total cost of ownership

Both sides of the comparison are usually incomplete. Builders forget maintenance and on-call; buyers forget that the price at ten times today's usage is a different number.

Build TCO (3 years) =
    initial build effort
  + 3 x annual maintenance       (bug fixes, upgrades, dependency and security patches)
  + 3 x annual on-call load      (incidents, alert handling, after-hours time)
  + infrastructure and tooling
  + compliance work              (audit evidence, pen test scope for the new component)
  + opportunity cost             (roadmap work those engineers did not ship)
 
Buy TCO (3 years) =
    subscription at projected usage, year by year
  + integration build effort
  + 3 x annual integration upkeep (API version changes, webhooks, SDK upgrades)
  + workaround effort for missing features
  + vendor management            (security reviews, contracts, renewals)
  + exit cost                    (migration effort and running both systems during a switch)

Convert effort to money with your fully loaded engineering cost. Three practical notes:

  • Estimate maintenance from your own history, not a rule of thumb. Look at how much time your existing internal tools consumed last quarter in tickets, incidents and upgrade work. That is the best predictor you have.
  • Price the vendor at one, three and ten times current usage. Per-seat, per-active-user and per-event pricing behave very differently as you grow. Get the projected-volume price in writing.
  • Include the features you will need for enterprise customers. SSO, audit logs, longer retention and data residency often sit on the top pricing tier.

Open source and self-hosting: the third option

Self-hosting an open-source project gives you control over data and cost without building from scratch. It is not free. Someone owns upgrades, security advisories, backups, capacity and the pager. If nobody on the team will do that, a hosted version of the same open-source project is often the better buy.

Check two things beyond features:

  • The license and who controls it. Licenses change. HashiCorp moved Terraform to the Business Source License in 2023 and the community forked it as OpenTofu; Redis changed its license in 2024 and Valkey was forked from it. Projects governed by a foundation are less exposed to this than projects owned by one company.
  • Release and security cadence. A project that ships security fixes quickly and documents upgrade paths is cheap to run. One that breaks configuration on every major version is not.

Self-hosted software is part of your supply chain. Our guide to software supply chain security covers tracking what you run and patching it.

Vendor due diligence checklist

Run this before signing anything that will hold customer data or sit in a critical path.

  • Data export: full export in a documented format, through the API, without a support ticket
  • API stability: a versioning policy, a deprecation notice period and documented rate limits
  • Webhooks: signed, retried on failure and replayable from a dashboard or API
  • Reliability: public status history, an SLA with credits and clear incident communication
  • Security: a current SOC 2 Type II report or ISO 27001 certificate, a subprocessor list and data residency options
  • Price at scale: a written quote for projected volume, and a list of features gated to higher tiers
  • Contract: renewal price caps, termination terms and data deletion on exit
  • Vendor health: whether this product is core to the vendor or a side project that could be sunset
  • Lock-in inventory: what would live only inside the vendor (rules, workflows, templates, history)

Keep vendors behind your own interface

The cheapest exit plan is architectural. The application talks to an interface you own, expressed in your domain's terms, and one adapter per vendor translates. Nothing else imports the vendor's SDK.

// email/port.ts: the only email API the application imports
export interface OutboundEmail {
  to: string;
  template: "welcome" | "password-reset" | "invoice";
  data: Record<string, string>;
  idempotencyKey: string;
}
 
export interface EmailSender {
  send(msg: OutboundEmail): Promise<{ providerId: string }>;
}
// email/vendor-a.ts: one adapter per vendor; nothing else knows its API
import type { EmailSender, OutboundEmail } from "./port";
 
export class VendorAEmailSender implements EmailSender {
  constructor(private apiKey: string, private baseUrl: string) {}
 
  async send(msg: OutboundEmail) {
    const res = await fetch(`${this.baseUrl}/v1/send`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${this.apiKey}`,
        "Content-Type": "application/json",
        "Idempotency-Key": msg.idempotencyKey,
      },
      body: JSON.stringify({ to: msg.to, template: msg.template, vars: msg.data }),
      signal: AbortSignal.timeout(5000),
    });
    if (!res.ok) throw new Error(`email send failed with status ${res.status}`);
    const body = (await res.json()) as { id: string };
    return { providerId: body.id };
  }
}

Run the same contract tests against a fake adapter and against the vendor's sandbox. When you switch vendors, the new adapter has to pass the same tests, and the rest of the codebase does not change.

Hybrid patterns that work

Buy now, build later, with a written trigger. Buy to ship this quarter, and write down the condition that would justify building: a volume, a missing capability or a price threshold. Without the trigger, "later" never arrives or arrives too late.

Build the core, buy the periphery. Build the ranking logic; buy the search engine it runs on. Build the pricing rules; buy the payment processor. Our guide to implementing SaaS pricing shows where that line usually sits for billing.

Own the data, rent the tool. Send events through your own tracking module and copy them to your warehouse, then send them on to the analytics vendor. Switching vendors keeps your history.

Self-host only the expensive part. Keep a hosted error tracker, but route high-volume debug logs to cheap object storage you control.

Record the decision

Write each significant decision as an Architecture Decision Record. The revisit conditions are the most important part, because they turn a permanent argument into a scheduled check.

## ADR-014: Buy product analytics
 
Status: Accepted, 2026-10-04
Decision: Buy. Weighted score 1.9 (matrix attached).
Assumptions: Event volume triples within 12 months. EU data residency available.
Exit plan: Events go through our tracking module and are copied to the
warehouse nightly, so history survives a switch.
Revisit if: annual cost passes the agreed threshold, EU residency is withdrawn,
or we need joins with billing data the tool cannot do.
Owner: Growth team lead

Built systems need the same honesty. Internal tools that nobody owns are a common source of the debt described in our technical debt management guide.

What goes wrong in production

The build-versus-buy failures that reach the pager tend to be these.

A vendor outage with no fallback. The identity provider goes down and nobody can log in. Design for it: reasonable session lifetimes so existing users stay signed in, queues in front of email and SMS so messages send later, and alerts wired to the vendor's status feed.

Rate limits discovered during a launch. A bulk import or a marketing spike hits the vendor's API limits at the worst possible time. Read the limits before launch, and load test against the sandbox.

Webhook gaps cause state drift. A missed webhook leaves your database disagreeing with the vendor's. Run a nightly reconciliation that reads state from the vendor API and corrects your copy.

Price change or acquisition. The vendor triples its price at renewal or is acquired and sunsets the product. If your exit plan was never tested, you are negotiating with no leverage.

The weekend tool that became critical. An internal service built quickly by one engineer is now in the order path, and that engineer has left. Assign an owning team to everything in production, including tools.

Self-hosted software nobody upgrades. It runs fine until a critical CVE lands and the upgrade path crosses two major versions. Put upgrades on a calendar, not on a wish list.

The enterprise tier surprise. A large deal requires SSO, SCIM and audit logs from a vendor that only offers them on a plan priced for much larger companies. Price these before you commit.

Frequently Asked Questions

When should a company build software instead of buying it?

Build when the capability is part of why customers choose you, when no product meets a hard requirement, or when vendor pricing at your projected scale clearly exceeds the full cost of building and running it yourself. Buy everything else. Most companies should build their core domain logic and buy commodity infrastructure such as authentication, payments and email delivery.

How do you calculate total cost of ownership for build vs buy?

Compare three years of costs on both sides. For building, include the initial build, annual maintenance, on-call load, infrastructure, compliance work and opportunity cost. For buying, include the subscription at projected usage, integration work, ongoing upkeep, workarounds, vendor management and the cost of leaving.

Is open source build or buy?

Self-hosted open source is a third option between the two. You skip writing the software but take on upgrades, security patches, backups and on-call for it. If nobody on your team will own that work, a hosted version of the same open-source project is usually the better choice.

Should a startup build its own authentication?

Almost never. Authentication is security-critical, full of edge cases such as account recovery, MFA and SSO, and it differentiates nothing for most products. Use a managed identity provider or a mature open-source identity server, and check early which pricing tier includes the SSO and SCIM features enterprise customers will ask for.

How do you avoid vendor lock-in when buying software?

Put every vendor behind an interface you own so that only one adapter knows the vendor's API. Keep a copy of important data in your own storage, confirm that full export works before you sign, and write down the conditions that would make you switch. Lock-in becomes a problem mainly when nobody planned the exit.

Need help with a build-or-buy decision?

We are senior engineers who build systems and stay on to run them: if we built it, we are on the pager. That makes us honest about the maintenance side of the ledger. We can score a decision with you, review a vendor's integration risks, or build the part that should be yours.