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. That weekend turns into 6 months, then 2 years of maintenance, then a team of 3 dedicated engineers maintaining something that Stripe, Auth0, or SendGrid already does better for $50/month.
The opposite mistake is equally costly: buying expensive enterprise software for your core competitive advantage and then spending years fighting its limitations. This guide helps you make the build-vs-buy decision rationally, not emotionally, by analyzing competitive advantage, modeling total cost of ownership, and establishing vendor evaluation criteria.
The Decision Framework
Step 1: Is This Core to Your Business?
The single most important question: does this functionality differentiate your product in the eyes of your customers?
Is this functionality a competitive advantage?
│
YES ──▶ Consider BUILDING (it differentiates you)
│
NO
│
Do off-the-shelf solutions exist that meet 80%+ of your requirements?
│
YES ──▶ Consider BUYING (don't reinvent solved problems)
│
NO
│
Is the gap between available solutions and your needs > 40%?
│
YES ──▶ Consider BUILDING (but budget 3x your initial estimate)
│
NO ──▶ Consider BUYING + customizing
Core vs Context
| Category | What This Means | Examples | Default Choice |
|---|---|---|---|
| Core (differentiates your product) | This is why customers choose you over competitors | Recommendation engine, pricing algorithm, proprietary analytics, matching engine | Build — invest engineering here |
| Core-Adjacent (supports core) | Internal tools that make your core features better | Data pipelines, admin dashboards, workflow automation, internal APIs | Hybrid — buy commodity, build custom layer |
| Context (everyone needs it) | Solved problems that are table stakes | Authentication, email delivery, payments, CRM, HR, monitoring | Buy — don’t waste engineering on solved problems |
The Competitive Advantage Test
Ask these questions. If you answer “no” to all three, you should buy:
- Would customers choose your product BECAUSE of this feature’s implementation? (Not just that it exists, but that YOUR implementation is better)
- Does building this in-house give you a data or speed advantage that a vendor solution can’t match?
- Would a competitor building this themselves create competitive pressure that forces you to build as well?
Step 2: Calculate Total Cost of Ownership
Never compare just the build cost vs the license fee. Compare 5-year TCO including all hidden costs.
Build Cost Model
def calculate_build_tco(params):
# Year 1: Development
dev_team_annual = params["developers"] * params["avg_salary"] * 1.4 # 40% for benefits, taxes, equipment
dev_months = params["estimated_months"] * 1.5 # Add 50% buffer (projects always take longer)
dev_cost = dev_team_annual * (dev_months / 12)
# Ongoing: Maintenance (20-30% of initial build cost, every year, forever)
annual_maintenance = dev_cost * 0.25
# Infrastructure: hosting, monitoring, backups
annual_infra = params["monthly_infra"] * 12
# Opportunity cost: what ELSE could those engineers have built?
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),
}
# Example: Building a custom authentication system
build = calculate_build_tco({
"developers": 3,
"avg_salary": 160000,
"estimated_months": 6, # Will become 9 months with buffer
"monthly_infra": 2000,
})
# Result: ~$750K over 5 years
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"]
annual_price_increase = 1.05 # Assume 5% annual price increases
year_1 = annual_license + implementation + training
years_2_to_5 = sum(
(annual_license * annual_price_increase**y) + annual_integration
for y in range(1, 5)
)
return {
"year_1": round(year_1),
"annual_ongoing": round(annual_license + annual_integration),
"five_year_tco": round(year_1 + years_2_to_5),
}
# Example: Auth0 for the same authentication need
buy = calculate_buy_tco({
"per_user_monthly": 25,
"users": 200,
"implementation_cost": 50000,
"integration_maintenance": 15000,
"training_cost": 10000,
})
# Result: ~$440K over 5 years
print(f"Build 5-Year TCO: ${build['five_year_tco']:,}")
print(f"Buy 5-Year TCO: ${buy['five_year_tco']:,}")
print(f"Savings from buying: ${build['five_year_tco'] - buy['five_year_tco']:,}")
Common TCO Mistakes
| Mistake | Reality |
|---|---|
| ”It will take 2 months” | It will take 6-12 months |
| ”We won’t need to maintain it” | Maintenance is 25% of build cost EVERY year |
| ”We’ll just assign one junior dev” | It requires senior attention for security, scale |
| ”The vendor is too expensive” | Your 3 engineers cost more than any SaaS fee |
| ”We’ll open-source something” | Open-source still requires hosting, patching, support |
Step 3: Evaluate Vendors
If you’re leaning “buy,” evaluate at least 3 vendors before committing.
Vendor Scorecard
| Criteria | Weight | Score (1-10) | Weighted |
|---|---|---|---|
| Functional fit (% requirements met out of the box) | 25% | ___ | ___ |
| Integration capabilities (REST API, webhooks, SDKs) | 15% | ___ | ___ |
| Vendor financial stability (revenue, funding, profitability) | 15% | ___ | ___ |
| Security certifications (SOC 2, ISO 27001, HIPAA) | 15% | ___ | ___ |
| Customer references (similar size, similar industry) | 10% | ___ | ___ |
| Total cost of ownership (5-year) | 10% | ___ | ___ |
| Exit strategy (data export, API access, no lock-in) | 10% | ___ | ___ |
Vendor Red Flags
| Red Flag | Risk Level | What It Means |
|---|---|---|
| No public API or webhooks | 🔴 Critical | You can’t integrate — you’re trapped in their UI |
| No SOC 2 Type II report | 🔴 Critical | Security posture is unknown — deal breaker for enterprise |
| < 3 years in business, no funding | 🟡 Warning | May not survive to your contract renewal |
| No data export feature | 🔴 Critical | Your data is hostage — maximum vendor lock-in |
| Pricing only available “on request” | 🟡 Warning | Expect aggressive sales tactics and non-standard pricing |
| Single-tenant only | 🟡 Warning | May indicate outdated architecture and scaling limitations |
| No sandbox/trial environment | 🟡 Warning | They don’t want you to test before committing |
| Annual contracts only, no month-to-month | 🟡 Warning | Difficult to evaluate fit before long-term commitment |
Vendor Due Diligence Checklist
- Call 3+ customer references — ask specifically about support quality, downtime, and price increases
- Test with real data — never buy based on demo data alone
- Review the contract — look for auto-renewal clauses, price increase caps, termination fees
- Evaluate the API — build a proof-of-concept integration before signing
- Check the roadmap — does the vendor’s product direction align with your needs?
Step 4: Consider the Hybrid Approach
The best strategy is often: Buy the commodity, build the differentiation, integrate deeply.
┌──────────────────────────────────────────┐
│ YOUR PRODUCT │
│ │
│ ┌────────────┐ ┌──────────────────┐ │
│ │ BUILT │ │ BOUGHT │ │
│ │ (Your IP) │ │ (Commodity) │ │
│ │ │ │ │ │
│ │ Pricing │ │ Auth (Auth0) │ │
│ │ Engine │ │ Email (SendGrid) │ │
│ │ │ │ Payments (Stripe)│ │
│ │ Rec Engine │ │ CRM (HubSpot) │ │
│ │ │ │ Analytics (GA4) │ │
│ │ Proprietary│ │ Monitoring │ │
│ │ Analytics │ │ (Datadog) │ │
│ │ │ │ Search (Algolia) │ │
│ └────────────┘ └──────────────────┘ │
│ Competitive Everyone needs │
│ Advantage these — buy them │
└──────────────────────────────────────────┘
Real-World Hybrid Examples
| Company | Built (Core) | Bought (Context) |
|---|---|---|
| Netflix | Recommendation algorithm, streaming engine | AWS infrastructure, Slack, JIRA |
| Stripe | Payment processing engine | Salesforce CRM, Datadog monitoring |
| Shopify | Merchant platform, checkout | Stripe for payments, Zendesk for support |
| Airbnb | Search/matching algorithm, pricing | Twilio for SMS, SendGrid for email |
Decision Checklist
- Classified as core (build), core-adjacent (hybrid), or context (buy)
- Competitive advantage test applied (3 questions)
- 5-year TCO calculated for BOTH build and buy — including maintenance and opportunity cost
- Build estimate includes 50% buffer for overruns
- 3+ vendors evaluated if buying (scorecard completed)
- Vendor API tested with a proof-of-concept integration
- Vendor security certifications verified (SOC 2 minimum)
- 3+ customer references called (asked about support, downtime, price increases)
- Data portability verified (can you export ALL your data?)
- Contract reviewed for auto-renewal, price caps, and termination fees
- Decision documented as an Architecture Decision Record (ADR)
- Exit strategy planned regardless of build or buy choice
:::note[Source] This guide is derived from operational intelligence at Garnet Grid Consulting. For architecture advisory, visit garnetgrid.com. :::