Make vs. Buy Decisions
One of the most consequential decisions in IT project management is whether to build a solution in-house or buy (or subscribe to) an existing product. This decision impacts budget, timeline, control, maintenance burden, and competitive advantage.
| Factor | Build (Make) | Buy |
|---|---|---|
| Control | Full control over features and roadmap | Limited to vendor roadmap |
| Time to Market | Months to build from scratch | Days to weeks to integrate |
| Cost (Short-term) | High (engineering time) | Lower (subscription fee) |
| Cost (Long-term) | Maintenance and support burden | Recurring license fees scale up |
| Competitive Advantage | Can differentiate the product | Same capabilities as competitors using the same vendor |
| Risk | Execution risk, resource dependency | Vendor lock-in, vendor stability |
Decision Rule of Thumb
- Build when the capability is a core differentiator for your business
- Buy when it is commodity functionality (auth, email, payments, monitoring)
- Build when no vendor meets >80% of your requirements
- Buy when time-to-market is critical and a vendor exists
RFP/RFQ Process
// Vendor Evaluation Scoring Matrix
interface VendorEvaluation {
vendorName: string;
categories: {
category: string;
weight: number; // 1-5 importance
criteria: {
name: string;
score: number; // 1-5
notes: string;
}[];
}[];
totalScore: number;
recommendation: 'select' | 'shortlist' | 'reject';
}
function calculateVendorScore(evaluation: VendorEvaluation): number {
let weightedSum = 0;
let totalWeight = 0;
for (const category of evaluation.categories) {
const categoryAvg = category.criteria.reduce((sum, c) => sum + c.score, 0) / category.criteria.length;
weightedSum += categoryAvg * category.weight;
totalWeight += category.weight;
}
return Math.round((weightedSum / totalWeight) * 100) / 100;
}
// Example vendor comparison
const vendorComparison: VendorEvaluation[] = [
{
vendorName: 'Vendor A - Stripe',
categories: [
{
category: 'Functionality',
weight: 5,
criteria: [
{ name: 'Payment methods supported', score: 5, notes: 'Cards, wallets, bank transfers, BNPL' },
{ name: 'International support', score: 5, notes: '46 countries, 135+ currencies' },
{ name: 'Subscription billing', score: 5, notes: 'Full-featured recurring billing' },
{ name: 'Fraud detection', score: 4, notes: 'Stripe Radar included' },
]
},
{
category: 'Technical Integration',
weight: 4,
criteria: [
{ name: 'API quality', score: 5, notes: 'Best-in-class documentation and SDKs' },
{ name: 'Webhook reliability', score: 5, notes: 'Reliable with retry logic' },
{ name: 'Testing tools', score: 5, notes: 'Test mode, CLI, fixtures' },
]
},
{
category: 'Pricing',
weight: 3,
criteria: [
{ name: 'Transaction fees', score: 3, notes: '2.9% + 30c per transaction' },
{ name: 'Volume discounts', score: 4, notes: 'Available above $1M/year' },
]
},
{
category: 'Support & Reliability',
weight: 4,
criteria: [
{ name: 'Uptime SLA', score: 5, notes: '99.99% uptime' },
{ name: 'Support quality', score: 4, notes: '24/7 for premium plans' },
{ name: 'Vendor stability', score: 5, notes: 'Public company, strong financials' },
]
}
],
totalScore: 0,
recommendation: 'select'
}
];
// Contract types
type ContractType = {
name: string;
riskAllocation: string;
bestFor: string;
pmConsideration: string;
};
const contractTypes: ContractType[] = [
{
name: 'Fixed Price',
riskAllocation: 'Vendor bears cost overrun risk',
bestFor: 'Well-defined scope, clear deliverables',
pmConsideration: 'Requires detailed requirements upfront. Change orders are expensive.'
},
{
name: 'Time & Materials (T&M)',
riskAllocation: 'Buyer bears cost overrun risk',
bestFor: 'Evolving scope, R&D work, staff augmentation',
pmConsideration: 'Need strong oversight. Set budget ceilings and review milestones.'
},
{
name: 'Cost-Reimbursable',
riskAllocation: 'Buyer bears most risk',
bestFor: 'Highly uncertain scope (research, innovation)',
pmConsideration: 'Audit costs regularly. Set not-to-exceed limits.'
}
];
SLA Management
Essential SLA Components
- Uptime Guarantee: 99.9% (8.7 hours downtime/year) vs 99.99% (52 minutes/year) — each "9" is exponentially more expensive
- Response Time: How quickly the vendor acknowledges an issue (e.g., SEV-1: 15 minutes)
- Resolution Time: How quickly the vendor fixes the issue (e.g., SEV-1: 4 hours)
- Penalties: Service credits or refunds when SLA is breached (typically 10-25% of monthly fee)
- Exclusions: Scheduled maintenance, force majeure, customer-caused issues are usually excluded
Vendor Exit Strategy
Always plan for the possibility of leaving a vendor:
- Data Portability: Ensure you can export your data in standard formats
- API Abstraction: Use adapter patterns so switching vendors is a code change, not a rewrite
- Contract Terms: Negotiate reasonable termination clauses and transition periods
- Knowledge Transfer: Document all vendor-specific configurations and integrations