Skip to main content
Data Architecture

Knowledge graphs for enterprise data

A graph is a data model, not a strategy. Modelling takes a few weeks. Identity, edge history and change take years, and they are what decide whether the thing is useful.

The graph is the easy part

Almost every stalled knowledge graph we are asked to look at has a defensible model and no answer to one question: which decision gets better because this exists? The model is not where these programs fail. Someone draws nodes and edges on a whiteboard in an afternoon, the schema is agreed in a fortnight, and a loader runs by the end of the month. Then the project spends two years on the parts nobody put in the plan, which are identity, edge history, and what happens when a source system changes its mind.

That is not an argument against graphs. It is an argument for spending the planning effort where the cost actually lands. A graph is the right model for a real and identifiable class of problems, and the wrong one for a larger class where a relational schema and two materialized views would have shipped in a quarter. The difference is knowable up front, from the shape of the questions you need answered.

You are probably here because

  • Someone asked for “a knowledge graph” and nobody has written down what it is for
  • A graph exists, it loads nightly, and no product team queries it
  • Two people disagree about whether a company and a subsidiary are the same node, and both are right
  • An ownership hierarchy changed and every number you published last year quietly changed with it

The first two are scoping problems and the question test below covers them. The second two are the real engineering: identity, and putting time on every edge.

What a graph buys that a join does not

Three things, and it is worth being precise, because each of them has a relational workaround that a competent team can build. The question is not whether the workaround exists. It is how much of your year it consumes.

Traversal of unknown depth. “Which of our suppliers sit within four ownership hops of this counterparty” is expressible in SQL with a recursive common table expression, and it works fine at small fan-out. It degrades badly when the intermediate result set explodes, and it degrades unpredictably, because the planner has no idea how many rows hop three will produce. Graph engines are built around this access pattern, and the practical difference shows up as a query you can put behind a user-facing screen rather than one you run overnight.

Edges as first-class objects. A relationship in the real world has a start date, often an end date, a source, a method by which it was established, and sometimes a human who adjudicated it. All of that fits in a relational link table. In practice teams do not build it that way: the link table starts as two foreign keys, the dates get added under pressure two years in, and the provenance never arrives. A graph model makes the attributed edge the default rather than the exception, and that default is most of the value.

Sparse, heterogeneous attributes. When you have four hundred possible attributes and a typical entity carries twelve, a wide table is mostly nulls and a table-per-type schema turns into ninety tables with a migration each. Graphs tolerate this shape natively. That is a modelling convenience rather than a capability, but it is a real one when the source systems keep adding fields.

WorkloadDoes a graph earn its place?What we would build instead
Fixed two- or three-table joins, known in advanceNoRelational schema plus a materialized view. Ships in weeks
Ownership, control and beneficial-interest chainsYesGraph, with effective dates on every edge
“How are these two things connected” with no fixed pathYesGraph. This is the query type nothing else answers well
Aggregation over billions of rowsNoColumnar warehouse. Graph engines lose this badly
Lineage across pipelines, tables and reportsYesGraph, and usually a small one that pays for itself fast
Product catalogue with a stable, shallow hierarchyNoRelational with a closure table if depth is bounded

The question test, before any modelling

Write down the five questions the graph is supposed to answer, in the words the person asking would use. Then look at their shape. If every one of them is two joins deep, and the joins are known in advance, you do not have a graph problem, you have a schema and a caching problem. If two or more of them involve a path of unknown length, or a “how is A connected to B” where nobody can name the intermediate hops, the graph is earning something.

The test has a second half that people skip. For each question, name the decision that changes when the answer arrives, and name the person who makes it. A question with no decision behind it is a demo. We have watched a fully functional graph sit unqueried for eighteen months because every question in the original charter was interesting rather than load-bearing.

Identity is the project

The node is not the hard part; deciding what counts as one node is. A legal entity in three source systems arrives as three records with three identifiers, two spellings and one address that is a mailbox service. The graph forces the question that the relational world lets you defer, because in a graph, merging two things that are not the same silently rewires every path through them.

Three rules we hold to. Never use an external identifier as a primary key. Vendors reuse them, retire them, and change their licensing. Mint an internal surrogate id, and carry the external ones as attributes with their own validity dates. Store the match, not the merge. A resolution decision is an object with the signals that supported it, the threshold in force at the time, and any human adjudication, which means it can be reviewed and reversed. A merged node with the evidence thrown away cannot be. Give unresolved its own state. “We do not know whether these are the same” is a distinct and useful answer, and collapsing it into either “same” or “different” is where the wrong numbers come from.

A knowledge graph with unreliable identity is an unusually expressive way to be wrong, and it is confident about it.

Budget accordingly. On the integrations we have worked, identity and its ongoing maintenance is routinely a third to a half of the total effort, and it does not stop when the project does. Sources refresh, reintroduce variants you resolved, and occasionally renumber themselves. Plan for a standing job, not a cleanup.

Every edge needs a time and a source

Two clocks, and they are not the same clock. Valid time is when the fact was true in the world: this company owned that subsidiary from March 2024 to January 2026. Assertion time is when you came to believe it: the filing reached you in May 2024, and a correction arrived in August. Systems that carry only one of these cannot answer the question every dispute eventually becomes, which is “what did we believe on the fourteenth, and on what basis?”

The minimum viable edge record carries: valid from, valid to, asserted at, source system, source document reference, extraction or match method, and confidence where confidence means something. That is seven fields on top of the two endpoints, and it is the single highest-return decision in the whole design. Retrofitting it is close to impossible, because the history you needed was never captured.

Where the effort actually goes — our planning split for a first graph

Identity resolution and its maintenance
35
Source ingestion, change capture, reconciliation
25
Serving layer and the queries product teams run
15
Schema, ontology and vocabulary work
10
Stewardship tooling and adjudication queue
10
Choosing and standing up the database
5

Weights sum to 100. Our planning starting point, not a measurement. The point is the ordering: the database selection everyone argues about is the smallest line.

Ontology: grow it, do not legislate it

The most reliable way to lose a year is to convene a committee to define the enterprise ontology before anything loads. The output is comprehensive, internally consistent, and describes a company that does not exist, because the people who know how the data actually behaves are the ones loading it.

Start with eight to fifteen node types and the edges between them. Add a type only when it answers a question the existing types answer badly, and write that question in the commit message. Where a published vocabulary already covers your domain, borrow its terms even if you do not adopt its full machinery, because the naming arguments you avoid are worth more than the purity you give up. Then make the shapes testable: constraint checks that run in the pipeline and fail the load when an edge points at the wrong type or a required date is missing. An ontology nobody enforces is a document, and documents drift.

Property graph or RDF

This argument consumes more meeting time than it deserves. Both work. The decision follows from one thing: whether you control the vocabulary.

ApproachChoose it whenWhat it costs you
Property graph
Cypher, GQL, Gremlin
You own the sources and the vocabulary; the team is application engineersWeaker story for merging outside vocabularies; inference is yours to build
RDF
SPARQL, SHACL, OWL
You merge vocabularies you do not control, or need globally resolvable identifiersSteeper learning curve; statements about statements need extra machinery; fewer engineers on the market
Relational with recursion
Recursive CTEs, closure tables
Depth is bounded and known, and you already run a warehouse wellPath queries get slow and stay slow; attributed edges rarely get built

Two practical notes. The graph query language landscape settled meaningfully when GQL became an ISO standard in 2024, which weakens the lock-in objection that used to decide this by default. And whichever side you pick, expect the storage footprint to surprise you: an attributed, bitemporal edge with provenance is several times the size of the two identifiers it connects, and history means you never delete.

The graph is usually not the query path

A pattern worth adopting early: the graph is the system of record for relationships, and something else serves the application. Product screens have known access patterns, tight latency budgets, and no interest in traversal. Materialize what they need — a flattened ownership rollup, a neighbourhood snapshot, a denormalized document per entity — and refresh it from the graph on a schedule the consumers agree to.

This costs a pipeline and buys three things: the application stops being coupled to graph query performance, the graph stops being on the critical path for a page load, and you can change the graph model without a coordinated release across four teams. Teams that skip it end up defending traversal latency in a product review, which is a conversation nobody wins.

Send us the five questions and we will tell you if it is a graph.

Email the five questions the graph is meant to answer, in the words of the person who asked, plus the list of source systems, to contact@precisionfederal.com. You get back a short written note saying which questions need a graph, which need a view, and where the identity work sits. One business day. No charge, no meeting, no deck.

contact@precisionfederal.com

Graphs and language models, honestly

Graph-backed retrieval is real and it is oversold, usually in the same paragraph. What it genuinely helps with: questions requiring several hops, which vector search over chunks answers badly because no single chunk contains the answer; “how are these two entities connected”, which is the query type embeddings cannot express at all; and scoping — pulling a neighbourhood around a resolved entity and retrieving only within it, which cuts both the token bill and the rate of confidently wrong answers.

What it does not fix is extraction quality, and that is where the cost lives. Building a graph by having a model read a corpus means every relation in it is a model output with an error rate. For a tightly specified schema and a capable model, per-relation precision in the eighties is achievable and recall trails it, which means a human adjudication queue for the tail is not optional if anyone is going to act on the output. Price the re-runs too: at even a cent a document, a million-document corpus is ten thousand dollars per full re-extraction, and nobody re-extracts only once — you will do it again when the schema changes, when the model changes, and when you find a systematic error in the first pass.

Design Note

The graph's best contribution to a language-model product is not retrieval, it is grounding

When extraction links a mention to a canonical node id, every generated answer can cite the node and, through it, the source document, the date the fact was asserted and the confidence attached to it. That turns “the model said so” into a record with a provenance chain a reviewer can follow. Teams reach for the graph to improve recall and end up keeping it for the audit trail.

What it costs

For three to five sources, an entity population in the low millions, and one product team as the consumer, we plan a first useful graph at eight to fourteen weeks with two or three engineers, plus a domain person available for roughly a day a week to adjudicate identity questions. That last resource is the one that gets promised and not delivered, and its absence is the most common reason the timeline doubles.

Infrastructure is rarely the constraint at this size — a single well-provisioned instance handles a graph of a few hundred million edges. Steady-state cost is dominated by people: someone owns identity, someone owns the source contracts, and someone answers when a downstream number is disputed. If no name goes next to those three jobs at the start, the graph decays quietly and is abandoned about eighteen months later, usually with a note saying the technology did not work out.

The mistakes we are called in to fix

  • Modelling before the questions are written down, producing a schema that answers nothing in particular
  • External identifiers as primary keys, so a vendor renumbering breaks every edge
  • Merged golden nodes with the match evidence discarded, making a bad merge unreviewable
  • Undated edges, so restating a hierarchy silently restates every number you ever published
  • Application queries pointed straight at the graph, coupling page latency to traversal
  • An ontology committee running a year ahead of the first loaded record
  • Model-extracted relations promoted straight to fact with no adjudication queue for the tail
  • No named owner for identity, which is how a working graph becomes an abandoned one

A first graph in eight weeks

Graph build sequence

1
Write the five questions and name the decision behind each one
Week 1
2
Profile the two hardest sources; measure identifier overlap and duplication before designing anything
Week 2
3
Model the smallest schema that answers the five questions; write the shape constraints as tests
Week 3
4
Build identity: blocking, scoring, thresholds, match objects, adjudication queue
Weeks 4–6
5
Load with full edge history; run the five questions and time them honestly
Week 7
6
Materialize the serving views a product team will actually call, and hand them over
Week 8

Step two is the one teams want to skip and the one that saves the schedule. Half an hour of profiling tells you whether the two systems share any usable identifier, and that single fact moves the identity estimate by a factor of three in either direction. Design before profiling is design against an imagined dataset.

If nobody can name the person whose decision changes when a question is answered, the graph is a demo with a database bill attached.

Before you commit

  • Five real questions written down, each with a named decision-maker behind it
  • At least two questions genuinely need a path of unknown length
  • Internal surrogate ids everywhere; external identifiers are dated attributes
  • Match decisions stored as objects with signals, thresholds and adjudication
  • Unresolved is a first-class state, distinct from matched and unmatched
  • Every edge carries valid time, assertion time, source and method
  • Shape constraints run in the pipeline and fail the load
  • A serving layer between the graph and any user-facing screen
  • Named owners for identity, source contracts and dispute response
  • Model-extracted relations flagged as such, with an adjudication path

Bottom line

Graphs earn their place on connection questions with no fixed path, and on relationships that need history and provenance attached. They lose to a warehouse on aggregation and to a relational schema on known joins, and choosing one for a workload of that second kind is how a competent team spends a year producing something nobody queries. If you do build one, spend the planning attention on identity and on putting two clocks on every edge. Those are the two decisions you cannot retrofit, and everything else in the design can be changed in place later without anyone downstream noticing.

Frequently asked questions

How do I know whether my problem actually needs a graph?

Write the five questions it must answer and look at their shape. If the joins are known in advance and two or three deep, a relational schema with a materialized view will ship faster and run faster. If two or more questions involve a path whose length nobody can state up front, or a “how are these connected” with unnamed intermediate hops, a graph is doing real work.

Property graph or RDF?

Property graph if you own the sources and the vocabulary and your team is made of application engineers. RDF if you are merging vocabularies you do not control or need globally resolvable identifiers. Both are viable for most enterprise work, and the decision matters far less than identity design, which is where the year goes either way.

Why not merge matched records into one golden node?

Because the merge discards the evidence and makes the decision unreviewable, and in a graph a wrong merge silently rewires every path through the merged node. Keep both records, store the match as its own object with the signals and threshold that produced it, and let downstream consumers choose a confidence cut-off appropriate to what they are doing.

Can a language model build the graph for us?

It can build a draft, and that is genuinely useful on unstructured corpora nobody has time to read. Treat every extracted relation as an assertion with a source, a method and a confidence, not as a fact. Plan a human adjudication queue for low-confidence output and budget for full re-extraction more than once, because the schema and the model will both change.

What does a first enterprise knowledge graph typically cost?

For three to five sources and an entity population in the low millions, plan eight to fourteen weeks with two or three engineers, plus about a day a week of a domain expert to adjudicate identity questions. Infrastructure is a minor line at that scale. Ongoing cost is a standing identity job, not a one-time cleanup, because sources keep changing underneath you.

1 business day response

Deciding whether to build a graph, or trying to revive one?

Send the questions it is meant to answer and the sources you would load. Our engineers will come back with a read on whether the model fits, where the identity work sits, and what we would build first. Email bo@precisionfederal.com.

Email an engineerCapabilitiesMore insights →
Knowledge GraphsEntity ResolutionData ArchitectureOntology Design