A dedicated development team can be cheaper to start than an in-house team and still become the more expensive decision if only the vendor knows how to change the system. I would select a vendor by testing whether my engineers could take over its work, not by comparing résumés or sprint output. The purchase should preserve the option to build in-house later.
A vendor trial should prove you can leave it
The most useful procurement question is specific: can an engineer who did not work on the project make a meaningful change after the vendor leaves? A polished handover presentation cannot answer it, because the missing knowledge often sits in deployment choices, undocumented data assumptions, and the reasons a library was selected. A takeover exercise can expose those gaps while the vendor is still available to fix them.
Give shortlisted vendors the same bounded assignment, such as implementing a subscription-renewal workflow in an existing service. Require an OpenAPI 3.1 contract for the endpoint, JSON Schema 2020-12 definitions for emitted events, and a PostgreSQL 16 migration for the durable business state. Those artifacts are useful because an internal team can inspect behavior without learning the vendor’s workflow engine first. The task should use a realistic repository and deployment boundary, since a greenfield demonstration hides the cost of working within your conventions.
In an illustrative paid trial, I would allow six weeks for implementation; that is a planning window to adjust to the scope, not a universal benchmark. Before the final demonstration, I would give two internal engineers a change request the vendor has not seen: add a renewal grace period and explain what happens to renewals already in flight. Their ability to make and release that change is more informative than a slide deck, because it tests whether the implementation has become an organizational asset.
Time the exercise, but record where the time goes. A two-day takeover target is an acceptance threshold I would tune to the size of the change. If most of it is spent finding undocumented credentials or discovering which database column is authoritative, the vendor has transferred code without transferring control. If the engineers understand the trade-offs yet need more time to implement the change safely, the result points to a different problem.
Is your dedicated team delivering value or just velocity asks a fair delivery question, but I would make replaceability a separate purchasing test because valuable output can still depend on one supplier to maintain it. The vendor should know this test before bidding; surprise exit drills reward defensive documentation rather than a workable collaboration.
The paid pilot should force a framework choice
Do not let a vendor win by promising to use whatever framework you prefer. Ask it to recommend an implementation, defend a rejected alternative, and show how either choice affects a later handover. This reveals whether the team can make trade-offs under your constraints rather than reproduce a familiar stack.
For the renewal workflow, compare Temporal with AWS Step Functions Standard. Temporal wins when complex, long-running application logic benefits from workflows expressed in code and the organization is prepared to own Temporal-specific development and operating practices. Its cost is that workflow history, worker versioning, and infrastructure or managed-service charges become part of the application’s long-term obligations. Step Functions Standard wins when the organization already operates on AWS and wants AWS-managed orchestration with an execution history its existing operators can inspect. Its cost includes state-transition charges and tighter dependence on AWS definitions, integrations, and IAM policies. Neither choice is inherently portable; the question is whether the domain behavior can be understood and reimplemented without reverse-engineering the orchestration configuration.
Require the vendor to keep the business contract distinct from the engine. A renewal event should carry a stable identifier and an explicitly defined grace-period rule; it should not require consumers to understand a Temporal workflow ID or a Step Functions execution ARN. Pact 4 contract tests can check a consumer’s expectations, while fixtures checked against JSON Schema can expose accidental changes to the event. These tests do not make migration automatic, but they give a replacement team something precise to preserve.
Ask the vendor to demonstrate one failed-payment retry, one duplicate event, and one workflow already running when the grace period changes. The purpose is to discover where behavior lives: in reviewed application code, in engine configuration, or in someone’s memory. A vendor that documents the rejected option and the migration boundary has made its recommendation easier to challenge; that is a strength when the CTO expects the system to outlive the engagement.
I would not demand a framework-neutral orchestration layer, because an abstraction that pretends Temporal and Step Functions have identical execution semantics adds code without removing the eventual migration work. I would demand a stable external contract and a written inventory of engine-specific assumptions, because those give an internal team a finite place to start.
The cheaper quote may have the higher replacement cost
Dedicated Software Development Teams Benefits and Costs provides a useful starting point for comparing team expenditure, but a buy-versus-build decision also needs a priced exit. The CTO should compare the cost of owning the capability over a defined horizon, not only the monthly invoice, because a vendor-led implementation can require internal hiring, migration work, or an extension at the moment the organization wants to change direction.
Request a quote with separate prices for implementation, ongoing changes, and a transition period in which the vendor supports an internal replacement team. Treat a quoted monthly rate as vendor-published pricing, not as a verified total: clarify whether it includes technical leadership, review of infrastructure changes, and time spent answering handover questions. For the in-house path, include recruiting and ramp-up as well as compensation, because a team that is not yet assembled cannot deliver on the same start date as an available vendor.
The following Python 3 calculation uses illustrative budget inputs, not observed market prices. Change the inputs to match both bids and your hiring plan:
python3 - <<'PY'
in_house_setup, in_house_monthly = 90000, 36000
vendor_setup, vendor_monthly, exit_cost = 15000, 46000, 20000
for months in (3, 6, 12):
build = in_house_setup + in_house_monthly * months
buy = vendor_setup + vendor_monthly * months + exit_cost
print(f"{months} months: build=${build:,}; buy=${buy:,}")
PY
The output is not a recommendation, because the exit-cost input is a hypothesis until someone attempts the takeover. Replace it with evidence from the trial: internal engineering time, vendor assistance, and any work needed to reconstruct deployment or domain rules. Then run at least two horizons. A vendor can be the rational short-term purchase and the weaker long-term owner when its head start is outweighed by recurring fees and transition effort.
Keep the decision tied to the capability being acquired. If the renewal system is expected to change frequently with product policy, an in-house team may earn back its setup cost through faster independent decisions. If it is a bounded delivery gap with a credible handover, buying can preserve hiring capacity for work that needs permanent internal judgment. Those are reasons to choose different ownership models, not claims that one staffing model is universally better.
Contract terms decide whether the exit drill is real
A successful pilot proves little if the production agreement prevents the same transfer. Put the repositories, CI configuration, infrastructure definitions, documentation, and relevant accounts under your organization’s control from the start. GitHub Actions workflows and Terraform 1.8 configurations should be reviewable in your repositories; Docker Compose v2 can provide a local path for the pilot’s dependencies. These choices do not guarantee maintainability, but they let your engineers test whether the instructions match the delivered system.
Require a dependency inventory using SPDX 2.3 identifiers and identify any proprietary component the vendor expects to keep. The point is not to reject all third-party code: it is to prevent a late discovery that the replacement team lacks a license or access to a component needed to build. Record who owns the domain, cloud account, container registry, and release credentials, since possession of source code alone does not confer the ability to ship a change.
Make handover an acceptance event rather than a promise at termination. For example, schedule an internal-led change before the last pilot payment, with the vendor observing and answering questions but not driving the keyboard. Set an eight-hour vendor-response window as a service term to negotiate for that exercise, rather than assuming the team will remain instantly available. Record questions that could only be answered orally and require the resulting decisions to be added to the repository. That creates a checkable record for the next engineer.
The contract should also specify how work in progress changes hands: the location of open issues, the status of partially completed migrations, and who may merge or deploy during transition. Avoid asking for a vast documentation package with no test of its use, because volume is easy to deliver and hard to assess. A short runbook that an unfamiliar engineer successfully follows is stronger evidence than an extensive document no one has tried.
Before issuing an RFP, write one takeover change request against an existing service and decide how your engineers will attempt it. Give every bidder that same test, the same access constraints, and the same definition of completion. You will then be buying evidence that the work can become yours—not merely a promise that a dedicated team can begin it.
