The build-vs-buy call most technical teams get wrong

The right question isn't whether a tool exists. It's where it stops fitting your problem.
By Vadim Zolotokrylin Vadim Zolotokrylin
TLDR

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 tell whether an off-the-shelf tool actually fits your problem — not just whether the feature exists, but whether its pricing model matches how you'd use it — 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: where exactly does the tool stop fitting the problem — a requirement it can't meet, or a pricing model that doesn't match how you'd use it — and does that gap 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.

Both halves of that are solved products. Calendly and cal.com's Collective and Round-Robin event types check multiple hosts' calendars and surface only the slots that work for everyone, and Calendly's single-use links, like cal.com's private links, stop working after a single booking. The capability we needed existed off the shelf.

What didn't fit was the shape of the bill. Collective and Round-Robin availability requires every host to hold a paid seat in the organization ( Calendly). Our requirement was "anyone on the team, " so the whole roster would need seats just to be listed as available, most of them booked rarely and some never. And generating those single-use links on demand, rather than clicking each one out by hand, means the Scheduling API, itself a paid tier ( Calendly). The real cost wasn't a subscription; it was a per-head license across the whole team for something each person would use a handful of times a year, with an API plan on top.

That is a different thing from "the cheap tier is too limiting." A plan you outgrow because you're getting more value out of it is worth paying for. A pricing model whose cost scales with the size of your roster while the usage scales with a few bookings a month is a model that doesn't fit the problem. That misfit, not the absence of a feature, is what justified building our own on a calendar API we already pay for.

The test that settles a build-vs-buy call has two edges, and we learned the first one the hard way. Name the one requirement and check whether the tool meets it at all, against the tool's current documentation, not memory or a half-remembered pricing page. Our own first pass failed exactly here: we recorded that no mainstream scheduler supported single-use links and built partly on that premise. It wasn't true, and a build decision resting on a feature that quietly exists is the precise failure this step is meant to prevent. Then, if the tool does meet the requirement, check whether its pricing model fits how you'd use it. "Annoying to configure" or "the free tier is too small" are reasons to pay for a better plan, not reasons to build. A cost that scales with your whole roster while the value scales with a few bookings is a genuine misfit, and a genuine reason to own the code.

What the underlying platform gives you, and what it doesn't

Building our own meant building on the calendar the team already lives in, and 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.

Correction (July 2026): an earlier version of this article claimed that no mainstream scheduler supports single-use booking links. Calendly and cal.com both do. The concrete case above has been revised, and the error itself is now part of the argument.

Have a suggestion? Edit this page