The build-vs-buy call most technical teams get wrong
The right question isn't whether a tool exists. It's which specific constraint it can't meet.If you've ever caught your team excited to build something in-house before anyone confirmed it was worth building, this article explains the one question that actually settles a build-vs-buy call. You'll learn why 'is there a tool for this' is the wrong first question, how to name the exact constraint an off-the-shelf tool can't meet, and why the urge to write code often outruns the evidence that the code is needed.
Most build-vs-buy conversations start with the wrong question: is there a tool for this. There almost always is. SaaS has covered most horizontal problems — scheduling, payments, auth, search — well enough that reaching for a tool is the right default nine times out of ten. The tenth time is where teams get it wrong in both directions: building something a tool already solves, or buying something that quietly breaks under a constraint the tool was never designed for.
The question that actually settles it is narrower: which specific requirement does the tool not meet, and does that requirement matter enough to justify owning the code.
A concrete case
We needed a way to let anyone on the team generate a link representing several people's real calendar availability at once, that an external contact could use to book a slot — and that link had to work exactly once. After it was used, it had to stop working, permanently, no matter who tried it next.
Calendly and cal.com both solve the first half of that well. Their Collective and Round-Robin event types check multiple hosts' calendars and surface only the slots that work for everyone. That's the hard part, and paying for it would have been the right call if it were the whole requirement.
It wasn't. Neither tool — nor, as far as we could find, any mainstream scheduler — supports a link that expires after a single booking. Every scheduling tool on the market is built around a durable, reusable link: one URL, booked repeatedly, forever. One-time-use isn't a missing feature buried in a pricing tier. It's a different object model. The link itself has to carry state — used or not — and every booking attempt has to check and lock that state atomically, or two people booking at the same moment could both succeed and leave the group double-booked. No amount of paid tier unlocks that, because it isn't what the product was built to do.
That's the whole test. Not "is this annoying to configure" or "is the free tier too limited" — those are reasons to pay for a better plan, not reasons to build. The test is: name the one constraint, and check whether it's structural to how the tool works, or just missing from your current plan.
What the underlying platform gives you, and what it doesn't
The same discipline applies one layer down. Google Calendar's own interface
has a "find a time" feature that looks like it solves availability
matching outright. It isn't exposed as a public API. The only relevant
endpoint, freebusy.query, returns busy blocks — not free ones. Computing
the actual free slots, intersecting several people's calendars, and
respecting each person's own working hours and timezone is left entirely
to whoever calls the API.
That's a second version of the same question: does the platform give you the primitive you need, or just a primitive that's adjacent to it. A team that assumes "Google must have an endpoint for this" builds on an assumption instead of a fact, and finds out the gap exists during implementation instead of during scoping.
Naming the constraint before you build
The discipline that makes this call correctly isn't "prefer building" or "prefer buying." It's naming the constraint precisely enough that the answer becomes obvious. "We want more control" or "the tool feels limiting" aren't constraints — they're discomfort, and they lead to building things that duplicate a tool for no real reason. "The token must be provably single-use, server-side, under concurrent access" is a constraint. It has a yes-or-no answer against any given tool, and once you have that answer, the build-vs-buy decision makes itself.
This is the same judgment call that shows up constantly in early-stage technical leadership — not writing more code, but knowing precisely which trade-off is in front of you before you commit resources to either side of it. Most teams don't lack the ability to build the harder version. They lack the habit of stating the constraint clearly enough to know whether they need to.
Building feels like progress even when it isn't the answer
There's a second failure mode underneath the first one, and it's easy to mistake for rigor. Writing code produces something you can point at by the end of the day: a commit, a passing test, a feature that runs. Talking to the people who'd actually use the thing produces nothing you can point at. It's slower, it's uncertain, and half the time it tells you the feature you were excited to build doesn't matter to anyone.
Engineers gravitate toward the version of the work that feels like progress, and building is almost always that version. The risk isn't that teams build too much — it's that they build before they've asked anyone whether the constraint they're solving for is even the right one. A constraint that's real but irrelevant to the people using the product is just as expensive as no constraint at all.
The fix isn't to build less. It's to put the conversation before the commit: confirm the constraint matters to the person on the other end of it, then decide whether a tool meets it. Skip that step and the discipline of naming a precise constraint just becomes a well-argued excuse to build the thing you wanted to build regardless.