Lesson 4 of 4 · 60 min

Build versus buy includes the exit cost

Compare two supplier options with a bounded decision table.

Buying a service can remove work from a small team, but the subscription price is only part of the decision. Consider integration, operation, failure recovery, data access, and the cost of leaving. Building can also hide costs because engineering time does not appear on the supplier invoice. Compare options against the same required outcome.
Begin with the nonnegotiable requirements. A hosted analytics service that cannot satisfy the product's data handling needs is not a cheap option for that workload. A home-built authentication system is not automatically safer because the team controls the code. Identify which parts of the problem differentiate the product and which parts are standard infrastructure that a supplier can manage well.
Use a time horizon. A temporary pilot tool may be suitable for a month even if its long-term cost is high. The decision should include a review date or usage trigger. Avoid an abstract debate about lock-in. Specify the export format, data ownership, replacement boundary, and behavior during supplier failure.
Build an adapter where it hides a meaningful supplier contract. Do not create a universal abstraction for capabilities the product does not use. A narrow function for creating a report job can keep provider-specific request fields out of the rest of the application. It must still expose important failure and identity semantics rather than flattening every provider result into success or failure.

Worked example

A fictional team needs scheduled report delivery for a pilot. Option A costs 150 units per month and takes two engineer-days to integrate. Option B costs 40 units per month in infrastructure but needs ten engineer-days to build and two days per month to operate. The team values one engineer-day at 200 planning units for this exercise. Over three months, A totals 850 units. B totals 3,320 units: 120 infrastructure plus 2,000 build plus 1,200 operation.
A meets the required export and access controls, so the team chooses it for the pilot. The decision includes monthly data export in an open format, a provider-independent report ID, and review if usage or missing capabilities change the comparison. These invented costs are an analysis exercise, not a provider recommendation.

Compare the same responsibility

A cost table is meaningful only if both options deliver the same required outcome. OptionA includes integration and subscription; optionB includes build, infrastructure, and operation. IfA omits a recovery capability thatB includes, the totals are not yet comparable. Add a valid workaround and its maintenance cost, or treatA as failing the requirement.
Three-month itemBuy ABuild B
Initial engineering2 days×200=40010 days×200=2000
Recurring infrastructure/subscription3×150=4503×40=120
Recurring engineering operationIncluded in suppliedA assumption3×2 days×200=1200
Modeled total8503320
The table uses invented planning values. In a real decision, supplier operation may still require internal incident response, configuration, and monitoring. If those are not included, record them as unknown or estimate them explicitly. Do not hide time because it is not invoiced.

Perform a sensitivity check

SupposeA requires one engineer-day per month of internal support after all. Its three-month total becomes 1450:850 plus 600. It remains belowB's3320 under these inputs, but the gap narrows. SupposeB's initial build already exists and needs only one day to adapt; its total becomes 1520:200 adaptation plus 120 infrastructure plus 1200 operation. The ranking can change with actual reusable capability.
Avoid treating sunk effort as a future cost. If a component is already built, compare the remaining adaptation and operating work from today. At the same time, do not assume existing code is free to maintain. Its compatibility, security, and failure handling still consume capacity.
A break-even analysis should state which values scale with usage. A fixed subscription may increase at a threshold; self-hosted costs may rise with storage and operator time. A straight line drawn from two pilot values can be misleading if either option changes pricing tier or requires a new operating role.

Define the supplier boundary

An adapter should preserve the semantics the product needs:
code
1submitDelivery(operationId, reportId, recipient) ->2  accepted(providerReference) |3  rejected(reason) |4  unknown(recoveryReference)56lookupDelivery(providerReference) ->7  pending | delivered | failed | unknown89exportHistory(from, to) ->10  portable records with product-owned report IDs
This is teaching pseudocode for an interface, not a claim about a particular vendor. It makes uncertainty visible rather than flattening every timeout to failed. A replacement provider must satisfy the product's required semantics or the product contract must change. A generic send function returning a boolean hides too much when duplicate delivery matters.
Keep product identity separate from provider identity. If all user history is keyed only by one supplier's opaque object ID, migration can become harder. Store the mapping needed to reconcile and export records, with appropriate access and retention. An adapter alone does not create an exit plan if the underlying data cannot be retrieved.

Test the exit before promising it

A monthly export is useful only if it contains the fields needed to continue operations elsewhere. Test a small export by reconstructing a known report's status and ownership in a neutral representation. Check timestamps, duplicate records, missing terminal states, and identifiers. A CSV file that omits delivery outcome may satisfy a file-download feature while failing the historical requirement.
Define outage behavior as well. Can queued work wait? Can the user retry without repeated delivery? Is there a manual fallback that remains authorized and auditable? A cheaper supplier may be acceptable with delayed delivery if the user promise allows it. It is not acceptable to silently redefine an immediate-delivery promise after purchase.

Misconceptions and a second exercise

One misconception is that buying eliminates engineering ownership. It shifts some implementation work but leaves integration, access, outcome verification, and supplier failure decisions. Another is that building guarantees portability. A tightly coupled internal system can be as difficult to replace as a supplier.
Exercise: A adds a required data-export plan costing 80 extra units per month and one engineer-day to verify the exported history. Recalculate the original three-month buy total. It becomes 1290:850+240+200. If the export still omits a required field, the option fails regardless of the lower price. Award one point for each added cost, one for 1290, and one for maintaining the requirement gate.
The final recommendation should name the chosen option, time horizon, supported requirements, cost assumptions, unresolved checks, and review trigger. It should explain what evidence would reverse the choice. That makes build-versus-buy a bounded engineering decision rather than an identity statement about the team.

Exercise and solution

Option A cannot export historical delivery status required by the product. What changes? It fails a required capability unless a safe supplementary record can satisfy the need. Recalculate only after defining that added work. Award one point for treating requirements as gates, one for including supplementary operation cost, and one for an explicit exit strategy.

Interview probe and wrap-up

When would you build despite a higher initial cost? A strong answer names a product-critical capability, unacceptable supplier constraint, or evidence that total cost changes at the expected scale. Follow up with a vendor outage. A weak answer says control is always worth any cost. Buy or build the smallest reliable responsibility boundary that fits the current product and preserves a credible next decision.

Sources

docsAWS cost-optimization frameworkdocs.aws.amazon.comdocsMartin Fowler on starting with a monolithmartinfowler.comdocsNext.js data security guidancenextjs.org

Checkpoint

A costs 850 over three months but needs one extra internal day/month at 200/day. Revised total?

A1050.B1250.C1450.D2050.
Sign up free to answer and see why

Checkpoint

Existing build code is already paid for. What belongs in today's comparison?

AThe whole historical build cost as if it must be paid again.BNo engineering cost because code exists.COnly the supplier invoice.DRemaining adaptation, operation, and risk costs, not already sunk effort.
Sign up free to answer and see why

Checkpoint

A timeout occurs after possible supplier acceptance. What should the adapter preserve?

AA boolean false with no reference.BUnknown outcome and a recovery identity under the supplier contract.CA new product operation ID for every retry.DA delivered state because the network request started.
Sign up free to answer and see why

Checkpoint

A portable file omits required historical outcomes. What follows?

AThe exit capability is incomplete; add a valid solution and cost or reject the option.BAny CSV proves an exit path.CLower price compensates automatically.DThe requirement can be removed without discussion.
Sign up free to answer and see why

Checkpoint

Original A850 plus 80/month export plan for 3 months and one 200 day verification totals?

A1690.B1090.C1050.D1290.
Sign up free to answer and see why

Can you compare equal responsibility, include internal operating and exit costs, and state the evidence that would reverse a supplier choice? State the relevant identifiers, failure boundary, and evidence in your own words before selecting your confidence.

Not yetGetting thereConfident

Sources

Free to read · better with Enzo

Learn it with Enzo

Save your progress, answer the checkpoints, and let Enzo quiz you on what you just read.