Any vendor writing this post has an answer before they start, so here is ours up front: sometimes you should build it, and we would rather say which cases than pretend there are none. A pitch that claims buying is always right is a pitch nobody senior believes.

The build case for BI has also got genuinely stronger. DuckDB, Parquet, Arrow and a competent model make a semantic layer and a dashboard renderer a plausible quarter's work for a good team. That is new, and it deserves a straight answer rather than a reflex.

Three cases where building is right

The caseWhy buying failsWhat you are actually building
Analytics is the productYou are embedding dashboards in software you sell. The look, the URL structure and the per-tenant isolation are product decisions, and a vendor’s roadmap is not yours.A rendering layer over your own model. Narrow, and you own the requirements.
One question, enormous scaleA single high-volume view — one fact table, one grain, one audience. A general BI tool is most of its cost in flexibility you will not use.A purpose-built page. Often a week, and correctly so.
A regulator owns your architectureConstraints that no vendor will meet on your timeline: an air gap, a specific jurisdiction, code review of everything that touches the data.Whatever the constraint dictates. The constraint is the requirement.

Notice what is not on that list: cost. “We can build it cheaper” is almost always an estimate of version one against a mature product, which is not the comparison you will live with.

xychart-beta horizontal
    title "Weeks over the estimate, by component"
    x-axis ["Charts", "Model", "Security", "Refresh", "Audit", "Migrate"]
    y-axis "Weeks over estimate" 0 --> 12
    bar [1, 10, 9, 4, 5, 9]
Chart rendering came in one week over, which is a good estimate. Model is the semantic layer and Security is row and column enforcement; between them they account for nineteen of the thirty-eight weeks of overrun. Audit and Migrate were not estimated at all, so their bars are their entire cost.

The question that actually decides it

Not “can we build this?” — you probably can. It is “who owns it in year two, when the person who built it has changed team?”

This is the failure mode nobody prices in, and it is specific rather than vague. An internal BI layer built by one strong engineer recreates the key-person dependency it was meant to remove — one level down, and now in code nobody else has read.

flowchart LR
    A["Year 1
one engineer, fast progress,
everyone delighted"] --> B["Year 2
they move to a
higher-profile team"] B --> C["Year 3
nobody will touch it"] C --> D["Year 4
a migration project
nobody planned"] style A fill:#e6f7f2,stroke:#9fd8c9 style C fill:#fff4e6,stroke:#f0cb9a style D fill:#fdecec,stroke:#eab6b6
The arc of most internal platform tools. Nothing goes wrong technically — the code keeps working. What fails is ownership, and it fails silently until something needs changing.

Ask it concretely before you commit: name the two people who will own this in eighteen months. If you cannot, or if the honest answer is “whoever is free”, that is the decision. Not a preference — the decision.

The incident in row three

Nine months in, a panel’s cached result was keyed on the query text alone. Two users with different row entitlements shared a cache entry, and one of them saw the other’s region for about forty minutes before someone noticed. Nothing was malicious and nothing left the building — but it was reportable, and the four weeks of rework was the cheapest part of it.

Version one was on time. Version three — with security that holds everywhere, scheduling that recovers, provenance a compliance team accepts, and a way off the old tool — was four times the estimate. Version three is what you are comparing against a product.

What people underestimate in a BI build

The rendering is the fun part and it is not the work. Four things consume a build, and three of them are invisible from the outside.

The workWhy it is underestimatedRough weight
Charts and layoutHighly visible, genuinely tractable with a grammar-of-graphics library.~15%
The semantic layer“Just SQL generation” until joins, grain, time grains, level-of-detail and derived fields arrive. Then it is a compiler.~30%
Row and column securityEasy to demo, hard to guarantee. It must hold on every path — dashboard, export, API, AI answer — and the cached-result key must include it.~25%
OperationsRefresh scheduling with backoff, extract versioning and rollback, audit, provenance, PDF rendering, a migration path off whatever you have now.~30%

The one that catches everyone

Caching and security are the same problem, and most builds discover this after go-live. If a panel’s result is cached on the query alone, two people with different row access share a cache entry and one of them sees the other’s numbers. The key has to include the policy — and the cleanest way to guarantee that is for the policy to already be inside the SQL the key is computed from.

That is a design decision you make once, early, and it is very unpleasant to retrofit.

The honest comparison

BUILDYou own the roadmap

Every feature is yours to prioritise, nothing is licensed per seat, and the thing fits your organisation exactly. You also own security holes, migration tooling, refresh reliability, and the staffing question above, permanently.

BUYYou own the definitions

The vocabulary, the dashboards and the data stay yours — in an open format, in your own cloud. What you do not own is the compiler, the policy engine, the importer and the operational surface. That is the trade, stated plainly.

The middle path most estates should take

The interesting option is rarely build-everything or buy-everything. It is: buy the governed layer, build the two or three things that are genuinely yours.

  1. The definitions are yours either way. A model is a readable, versioned document. That is the asset, and no product should hold it hostage.
  2. The data is yours either way. Parquet in your own bucket. If you removed the product, every file stays readable.
  3. Build the embedded surface if analytics is your product. Query through the API, render it yourself, keep your own look and URL structure.
  4. Do not build the compiler or the policy engine. These are where the subtle, expensive, security-relevant bugs live, and they are entirely undifferentiated. Nobody has ever won a customer because of their own GROUP BY generator.
How it was computed
The how-it-was-computed panel showing the logical query as readable JSON, the SQL that ran, and the row returned
What “buy the layer, keep the asset” looks like. The logical query is yours and portable; the compiler that turns it into SQL with your policies applied is the part you are buying.

If you have already built it

Most organisations reading this have something — a Streamlit app, a set of scheduled notebooks, a dbt layer with a thin viewer on top. That is not wasted, and it is usually the most valuable input available.

The dbt models are your definitions, already argued over. The scheduled queries tell you the real refresh cadences. The notebook nobody can retire tells you which questions actually matter. Bring all three to the evaluation rather than starting from a blank requirements document.

~30%of a BI build is the semantic layer
~25%is row and column security done properly
2 peoplename them, in eighteen months
Open formatwhat makes either choice reversible

The test to run before you decide

  1. Write down the two owners for year two. If you cannot name them, buy.
  2. Ask your security lead to describe how row security survives caching. If the build team has not thought about it, that is the size of the gap.
  3. Count the dashboards you would have to migrate. Build gives you no importer. Every one of them is rebuilt by hand, by someone, on a deadline.
  4. Price version three, not version one. Version one is a quarter. Version three — with scheduling, audit, export, provenance and migration — is the product you are actually comparing against.

If you buy: the first ninety days →  ·  How to tell whether it worked →

← All posts   Request a demo