Verified by Garnet Grid

How to Build vs Buy Software: A Decision Framework

Make rational build-vs-buy decisions. Covers total cost of ownership modeling, competitive advantage analysis, vendor evaluation, and hybrid strategies.

“We could build that in a weekend” is the most expensive sentence in software engineering. This guide helps you make the build-vs-buy decision rationally, not emotionally.


The Decision Framework

Step 1: Is This Core to Your Business?

Is this functionality a competitive advantage?

        YES ──▶ Consider BUILDING (it differentiates you)

        NO

Do off-the-shelf solutions exist?

        YES ──▶ Consider BUYING

        NO ──▶ Consider BUILDING (grudgingly)

Core vs Context

CategoryExamplesBuild or Buy?
Core (differentiates)Recommendation engine, pricing algorithm, proprietary analyticsBuild
Core-Adjacent (supports core)Data pipelines, internal tools, dashboardsHybrid
Context (everyone needs it)Auth, email, payments, CRM, HRBuy

Step 2: Calculate Total Cost of Ownership

Build Cost Model

def calculate_build_tco(params):
    # Year 1: Development
    dev_team_annual = params["developers"] * params["avg_salary"] * 1.4  # 40% benefits
    dev_months = params["estimated_months"]
    dev_cost = dev_team_annual * (dev_months / 12)

    # Ongoing: Maintenance (typically 20-30% of build cost annually)
    annual_maintenance = dev_cost * 0.25

    # Infrastructure
    annual_infra = params["monthly_infra"] * 12

    # Opportunity cost (what could the team have built instead?)
    opportunity_cost = dev_team_annual * (dev_months / 12) * 0.5

    # 5-year TCO
    year_1 = dev_cost + annual_infra + opportunity_cost
    years_2_to_5 = (annual_maintenance + annual_infra) * 4

    return {
        "year_1": round(year_1),
        "annual_ongoing": round(annual_maintenance + annual_infra),
        "five_year_tco": round(year_1 + years_2_to_5),
        "opportunity_cost": round(opportunity_cost),
    }

build = calculate_build_tco({
    "developers": 3,
    "avg_salary": 160000,
    "estimated_months": 6,
    "monthly_infra": 2000,
})

Buy Cost Model

def calculate_buy_tco(params):
    annual_license = params["per_user_monthly"] * params["users"] * 12
    implementation = params["implementation_cost"]
    annual_integration = params["integration_maintenance"]
    training = params["training_cost"]

    year_1 = annual_license + implementation + training
    years_2_to_5 = (annual_license + annual_integration) * 4

    return {
        "year_1": round(year_1),
        "annual_ongoing": round(annual_license + annual_integration),
        "five_year_tco": round(year_1 + years_2_to_5),
    }

buy = calculate_buy_tco({
    "per_user_monthly": 25,
    "users": 200,
    "implementation_cost": 50000,
    "integration_maintenance": 15000,
    "training_cost": 10000,
})

print(f"Build 5-Year TCO: ${build['five_year_tco']:,}")
print(f"Buy 5-Year TCO:   ${buy['five_year_tco']:,}")

Step 3: Evaluate Vendors

Vendor Scorecard

CriteriaWeightScore (1-10)Weighted
Functional fit (% requirements met)25%______
Integration capabilities (APIs)15%______
Vendor financial stability15%______
Security certifications (SOC2, ISO)15%______
Customer references (similar industry)10%______
Total cost of ownership (5-year)10%______
Exit strategy (data portability)10%______

Red Flags

Red FlagRisk LevelWhat It Means
No public API🔴 CriticalYou can’t integrate, you’re trapped
No SOC 2 report🔴 CriticalSecurity posture is unknown
< 3 years in business🟡 WarningMay not survive to renew
No data export feature🔴 CriticalVendor lock-in
Pricing only on request🟡 WarningExpect aggressive sales tactics
Single-tenant only🟡 WarningMay be outdated architecture

Step 4: Consider the Hybrid Approach

The best strategy is often: Buy the commodity, build the differentiation.

┌──────────────────────────────────────────┐
│              YOUR PRODUCT                │
│                                          │
│  ┌────────────┐   ┌──────────────────┐  │
│  │ BUILT      │   │ BOUGHT           │  │
│  │            │   │                  │  │
│  │ Pricing    │   │ Auth (Auth0)     │  │
│  │ Engine     │   │ Email (SendGrid) │  │
│  │            │   │ Payments (Stripe)│  │
│  │ Rec Engine │   │ CRM (HubSpot)   │  │
│  │            │   │ Analytics (GA4)  │  │
│  │ Prop.      │   │ Monitoring       │  │
│  │ Analytics  │   │ (Datadog)        │  │
│  └────────────┘   └──────────────────┘  │
│   Competitive      Everyone needs        │
│   Advantage        these                 │
└──────────────────────────────────────────┘

Decision Checklist

  • Classified as core (build) vs context (buy)
  • Calculated 5-year TCO for both options
  • Included opportunity cost in build estimate
  • Evaluated 3+ vendors if buying
  • Checked for API availability and data portability
  • Verified vendor security certifications
  • Called 3+ customer references
  • Documented the decision (Architecture Decision Record)
  • Planned exit strategy regardless of choice

:::note[Source] This guide is derived from operational intelligence at Garnet Grid Consulting. For architecture advisory, visit garnetgrid.com. :::