Skip to content

Technology Selection (Build vs. Buy vs. Reuse)

Technology selection decides whether to write custom code, buy an existing product, or reuse something the organization already has — before assuming “build” is the answer.

  • What it is: Evaluating build, buy, and reuse options against consistent criteria (cost, time-to-value, customization, vendor lock-in) for a given component of the solution.
  • Why it matters: building something that already exists as a mature product wastes months of engineering time; buying something that doesn’t fit the requirement wastes a contract and a migration later.
  • For developers: if you’re asked to build a component that sounds like “basically Salesforce” or “basically Kafka,” this is the analysis that should have happened first — worth asking for if it hasn’t.
  • When to use it: after Component & Integration Design identifies what a component needs to do.
  • When not to use it: for components that are genuinely core, differentiated intellectual property — those are usually built, not bought.
  • Prerequisites: a defined component boundary and its NFR targets.
flowchart TD
    A[Component need identified] --> B{Is it a core differentiator?}
    B -- Yes --> C[Build]
    B -- No --> D{Does an internal platform already do this?}
    D -- Yes --> E[Reuse]
    D -- No --> F{Does a mature product fit the requirement?}
    F -- Yes --> G[Buy]
    F -- No --> C

The decision tree defaults away from building: reuse or buy first, and only build when the component is a genuine differentiator or nothing else fits.

  1. Ask whether the component is a core differentiator for the business, or a commodity capability many organizations need.
  2. Check whether an existing internal platform already provides it — reuse avoids both build and vendor cost.
  3. If nothing internal fits, evaluate mature products against the requirement, weighing cost, time-to-value, customization limits, and vendor lock-in.
  4. Only build custom if the component is a genuine differentiator, or no existing option meets the requirement or NFRs.
  5. Record the decision and its criteria in an ADR, per Solution Options Analysis.

A sales team needs case management functionality; the in-house team estimates they could build it in about six months.

  • Input: options are build a custom case management tool, or buy a SaaS CRM and integrate via its API.
  • Process: a comparison table scores cost (SaaS subscription vs. six months of engineering time), time-to-value (SaaS live in weeks vs. months to build), customization (SaaS has some limits, custom build has none), and vendor lock-in (SaaS ties data to a vendor’s platform).
  • Output: the team buys the SaaS CRM — case management isn’t a differentiator for this business, and integrating via API is far cheaper and faster than building and maintaining custom software long-term. The six-month build estimate for the “custom” option had also quietly omitted hosting (Azure App Service), a database (Azure SQL Database), and identity (Microsoft Entra ID) — costs the SaaS subscription already includes.

Once “build” is the answer, most components map onto a small set of Azure building blocks rather than a from-scratch decision each time:

Capability Options When to pick which
Compute Azure App Service · Azure Functions · Azure Container Apps / AKS App Service for always-on web apps; Functions for event-driven/bursty workloads; Container Apps/AKS for containerized microservices needing fine-grained scaling control
Relational database Azure SQL Database · Azure Database for PostgreSQL Flexible Server Azure SQL Database fits a .NET/T-SQL-centric stack; PostgreSQL Flexible Server fits open-source-first stacks or workloads needing Postgres-specific extensions
NoSQL / global data Azure Cosmos DB Low-latency, globally-distributed reads/writes, flexible schema — see the async analytics example in Component & Integration Design
Object/file storage Azure Storage Account (Blob, Queue, Table, File) Static assets, large binary payloads, or the backing store behind a queue- or blob-triggered Azure Function
Observability Application Insights Should be wired in from the first NFR, not added after a production incident — see Non-Functional Requirements

Provisioning even the “build” option is real infrastructure, not just code — the six-month CRM estimate above was already missing this Bicep footprint for a lightweight custom service:

resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageAccountName
location: location
sku: { name: 'Standard_LRS' }
kind: 'StorageV2'
}
resource functionApp 'Microsoft.Web/sites@2023-01-01' = {
name: functionAppName
location: location
kind: 'functionapp'
properties: {
serverFarmId: consumptionPlan.id
siteConfig: {
appSettings: [
{ name: 'AzureWebJobsStorage', value: storage.listKeys().keys[0].value }
{ name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4' }
]
}
}
}
Use case When to use Notes
Common business capability (CRM, ticketing, identity) Not a differentiator for the business Default to buy unless a strong internal platform already exists
Core product feature Directly drives competitive advantage Usually build — buying would mean depending on a vendor for your differentiator
Capability already built elsewhere in the org Another team maintains a fitting platform Reuse it rather than building a second version
  • Vendor lock-in is a real cost, not a hypothetical one: factor in the cost and effort of switching away from a SaaS product later, not just the sign-up cost.
  • “Build” often hides a maintenance cost: the initial build estimate rarely includes years of ongoing patching, scaling, and feature parity work a mature product already has.
  • Reuse requires the same rigor as buy: an internal platform that doesn’t actually meet the NFRs is not a free option just because it’s already built.
  • Serverless narrows the build/buy gap, but doesn’t close it: Fowler’s Serverless Architectures notes FaaS/BaaS reduces “build” to mostly application code, cutting the operational cost gap with SaaS — but it also deepens vendor coupling, the same lock-in risk already named above, so it’s not a reason to skip the comparison.
Term Meaning
Build Develop custom software in-house for the component
Buy Acquire a commercial off-the-shelf (COTS) or SaaS product
Reuse Use an existing internal platform or service instead of building or buying new
Vendor lock-in The cost and difficulty of switching away from a vendor’s product later
Azure Functions Azure’s Function-as-a-Service (FaaS) compute option for event-driven, consumption-billed workloads
Azure Storage Account Azure’s object/file storage service (Blob, Queue, Table, File)
Azure Database for PostgreSQL Flexible Server Azure’s managed, open-source-compatible PostgreSQL offering
Application Insights Azure Monitor’s application performance monitoring service
Symptom Likely cause Fix
Team is building something that “sounds like” an existing product Build vs. buy analysis was skipped Run the comparison against real products before continuing custom development
SaaS product doesn’t fit after purchase Requirements weren’t checked against the product’s actual capabilities and NFRs Re-evaluate fit before renewal; document the gap for future selections
Build estimate keeps growing Original estimate didn’t include long-term maintenance cost Compare total cost of ownership, not just initial build cost, against buy/reuse options
  • Why does the decision tree default to reuse or buy before build?
  • Take a component you’ve built recently and check whether a build vs. buy comparison was ever done for it.

Part of Introduction to Solution Architecture. Follows Component & Integration Design; feeds into the Solution Architecture Document. See also the Glossary.