Skip to main content
All postsAutomation Strategy

Build vs Buy for Internal Tools: The Two Tests a Build Has to Pass

A decision framework from a firm that mostly tells clients to buy. The two tests a custom build has to pass before it wins, the failure modes nobody budgets for, and the first-party example where we took our own advice and built anyway.

Ross Devins
August 15, 2026 9 min read
Cover image for Build vs Buy for Internal Tools: The Two Tests a Build Has to Pass

Most of the time, we tell clients to buy. That's an awkward position for a firm that builds custom software, and it's the honest one. Somebody has already spent five years and a lot of engineering payroll productizing the thing you're about to spec, and their version has an onboarding flow, a mobile app, SOC 2 paperwork, and a support queue. Yours will have none of that in the first year.

But the advice isn't universal, and "always buy" is as lazy as "always build." There's a specific shape of problem where a focused internal tool wins clearly, and being able to recognize that shape is worth more than any general principle about software.

This is the framework we use, including on ourselves. Two tests have to pass before building wins. Then the failure modes, which are the part that sinks most builds, and a scoping test that keeps the honest builds small.

The default is buy, and the default is usually right

Start from the position that you should buy, and make the build argue its way out.

The reason is that the visible cost of a platform is the subscription, while the visible cost of a build is a quote, and those two numbers get compared as if they're the same kind of thing. They aren't. The quote covers getting to version one. The subscription covers the vendor continuing to employ people who fix bugs, ship compliance updates, keep integrations working when a partner changes their API, and answer the phone at 11pm. You are not comparing $X of software to $Y of software. You're comparing a purchase to an ongoing obligation you're taking on yourself.

A related trap: "we'll just build it in a weekend." The weekend version usually works. The problem arrives in month seven, when the person who built it is on a different project and somebody needs it to handle a case it was never designed for.

So the bar is high on purpose. Here are the two tests.

Test one: the money has to actually work

The per-seat cost of a platform that fits your process badly has to exceed the build cost inside roughly two years.

Two years is not arbitrary. It's about how long an internal tool goes before it needs meaningful rework anyway, so a payback period longer than that is really a bet that nothing about your business changes. Most bets like that lose.

Run the arithmetic properly, which means both sides get their full cost:

The buy side is more than the license. Add the seats you're paying for that nobody uses. Add the tier upgrade you took for one feature. Add the integration or middleware subscription that exists only to connect this platform to the next one. Then add the labor: if two people spend four hours a month reconciling what the platform can't express, that's most of a working week every quarter, at whatever your loaded cost per hour is.

The build side is more than the quote. Add hosting and any paid services it calls. Add maintenance, which we cover below and which people persistently forget. Add the cost of the person who has to learn it well enough to answer questions about it.

Where our own tiers land is a useful yardstick for the build side, since they're published: a small internal tool that replaces one spreadsheet sits in Starter or Workflow, $900 to $6,000 across one to four weeks. A real internal application with authentication, a data model, and a client-facing surface is Orchestration to Platform, $6,000 to $30,000 across four to twelve weeks. Our rate is $150 an hour and the project minimum is $2,500. The pricing page has the full breakdown, and what automation actually costs goes deeper on the arithmetic.

If the money doesn't work over two years, stop. Buy the platform, accept the imperfect fit, and spend the money somewhere it earns more. Plenty of things that annoy you are not worth $15,000 to stop being annoyed by.

Test two: the thing genuinely doesn't exist

The money test alone gets people into trouble, because you can always make a spreadsheet say building is cheaper. The second test is the one with teeth.

Has somebody already built this, and does it work? Not "is there a category," but has a real product solved the specific problem you have. Search properly before you conclude no. Look past the top three vendors, look at products aimed at adjacent industries, and look at whether the platform you already pay for has the capability behind a tier you haven't bought.

The distinction that matters is between a platform that can't do the thing and a platform that can do the thing but you'd have to configure it thoughtfully. Configuring it thoughtfully is nearly always cheaper than building. If your objection is that the fields are named wrong or the workflow takes an extra click, you have a preference, not a requirement, and preferences don't justify owning a codebase.

Here's the version that does justify it. Your process is common enough that plenty of firms run it, uncommon enough that no vendor optimizes for it, and central enough that getting it wrong costs real money. That combination produces a genuine gap, because a vendor with ten thousand customers rationally builds for the middle of their distribution, and you're in the tail.

Both tests have to pass. Money alone gives you a tool that duplicates something you could have bought. Uniqueness alone gives you an expensive monument to a minor irritation.

The example where we took our own advice and built anyway

We were paying for a well-known project-management platform and using it mostly as a timer with an invoice generator bolted on. It worked fine. What didn't work was concentrated in one place: how we bill.

Retainers are the clearest case. A client buys ten hours a month, uses six in July and fourteen in August, and unused hours roll forward exactly one month before expiring. Every platform we looked at either ignored that entirely or modeled it as a rigid bucket that resets at period end. So the real balance lived in a spreadsheet somebody reconciled by hand, which meant the number we invoiced from and the number in the system were different numbers. That's not a reporting annoyance. That's your billing running on a file with no tests, no audit trail, and no backup story.

Test two is the one that decided it. Retainer overage carry-forward is not exotic. It's how a large share of professional services firms actually bill, and the platforms model it badly because they were built around fixed-scope projects, where hours don't roll anywhere. That's exactly the shape where building wins: not because the incumbent is bad software, but because your process is a rounding error in their roadmap.

So we built Billable. Time logs against tasks with rate cards per client and per role. Retainer balances that carry overage forward on the schedule the contract specifies. Invoice drafts generated from approved time, held behind a review gate, because the failure mode with automated invoicing isn't a wrong number, it's a wrong number sent confidently. A client portal that turned a recurring awkward email into a link. Underneath it, the unglamorous half: restorable backups, an alerting path, 467 test assertions and 15 end-to-end suites. It replaced the platform subscription and it bills the invoices our clients receive.

That last detail is the point of publishing it. Every edge case in that build was hit with our own money on the line.

The failure modes nobody budgets for

Assume both tests passed. Here's what still goes wrong, in order of how often we see it.

Scope gets discovered rather than decided. This is the big one. Nobody sits down and specifies an internal tool completely, because the requirements live in people's habits rather than in a document. So you build, and in week three somebody says "obviously it also needs to handle the case where a client pays half up front," and that case was never in the estimate. Every one of those is reasonable in isolation. Collectively they're how a four-week build becomes a four-month build.

The mitigation is not better estimating. It's writing down what version one explicitly will not do, and keeping that list visible. A later-phase list that people can see is the only thing we've found that reliably stops discovered scope from becoming committed scope.

The maintenance tail. Software you own needs attention forever: dependency updates, a payment provider deprecating an API version, a browser change breaking one screen, a person requesting a field. Budget for it as a real line item rather than as goodwill, because unmaintained internal tools don't fail loudly. They drift into being slightly wrong, everyone works around them, and eighteen months later you're back to a spreadsheet beside the tool. Decide up front who owns maintenance and whether they have hours allocated to it.

The bus factor. One person built it, one person understands it, and that person eventually leaves, changes roles, or goes on holiday during month-end. This is the risk that turns a good internal tool into a liability, and it's the one buying a platform genuinely protects you from. Mitigations exist and they're boring: written documentation of the data model and the decisions behind it, tests that encode the business rules so the next person can change things without guessing, code somebody else has actually read, and a deployment process that isn't in one person's head. This is a lot of why we ship tests on internal tools even when the client didn't ask. Tests are the cheapest form of documentation that can't go stale.

Nobody uses it. Internal tools compete with the workaround people already have, and the workaround has a head start. If it's slower than the spreadsheet for the common case, it loses, whatever else it does well.

The smallest-useful-version test

When both tests pass and you decide to build, the question that keeps the project honest is this one.

Ask what replaces the spreadsheet, not what replaces the platform.

The spreadsheet is the thing somebody maintains by hand because the system can't hold it. It's where the real numbers live and it's the actual source of pain. It's also small. Replacing it is a well-defined job with an obvious done condition.

Replacing the platform is a different project by an order of magnitude, because the platform has years of features, and the moment you frame the goal that way you inherit all of them as requirements. Time tracking, sure, but also project templates, Gantt charts, resource planning, file attachments, comment threads. None of those were the problem. They came along because of how the goal was phrased.

We applied this to our own build and it's why version one shipped. The question was never "what would replace the project-management platform." It was "what removes the retainer spreadsheet and the reconciliation with it." Everything else went on a later-phase list and mostly stayed there, which is the correct outcome for a later-phase list.

It's a good filter for reading vendor evaluations too. If your team is comparing feature matrices across four products, ask which line in the matrix is the spreadsheet. Usually one is, and the other forty are noise you're paying to compare.

Running the decision this week

Write down the process the platform can't express. Find the spreadsheet or the manual step that exists because of it, and put a number on what that costs monthly in labor and errors. Then check whether a product already solves it, properly, including inside tools you already pay for.

If a product solves it, buy it and move on. If nothing does, and the two-year math clears, scope the smallest thing that kills the spreadsheet. We build custom internal applications when that path leads there, and we talk people out of it about as often as we take the work.

One thing to be careful of while you do this. The spreadsheet is not always evidence of a gap. Sometimes it exists because one person prefers it, or because nobody ever asked whether the platform could hold that data, and if you skip straight from finding it to scoping a build you'll spend fifteen thousand dollars formalizing a habit.

Want us to automate this for you?

Request a call: no pressure, no commitment.