Enterprise Knowledge Graphs
SQL to Neo4j: An Enterprise Migration Playbook
Published 2026-08-31 · Agentic Giants
TL;DR
Agentic Giants' engineers cover when a relational schema starts charging rent on enterprise queries, how to model foreign keys as graph relationships, and the one entity type most relational databases structurally cannot hold: a decision, with its own rationale, evidence, and history. Most migrations start as a parallel system rather than a wholesale replacement.
When should an enterprise migrate to a graph database?
When the shape of your queries changes, not before. A normalized relational schema with recursive queries handles two or three hops over a few million rows perfectly well, and teams that reach for a graph database before that ceiling is real end up running a second system for no benefit. The signal to watch for is a query planner whose cardinality estimates get worse at every additional join: by the fourth or fifth hop, a chain of joins is one bad statistics refresh away from a nested loop scan over the whole table, and the second such query, and the thirtieth, stop being queries you write and start being a query zoo you hand maintain.
A property graph's advantage is structural, not magic: following a relationship is a local pointer dereference from a node, not a global index lookup, so it doesn't get slower as the rest of the graph grows. Variable depth traversal is a language primitive rather than a hand written recursive query you'll get subtly wrong. And adding a new relationship type is a write, not a schema migration: which matters most in exactly the enterprise environments where the interesting relationships tend to get discovered after the system is already live.
How do you model relational foreign keys as graph relationships?
A foreign key becomes a directed relationship between the two nodes it used to connect indirectly through an id column. A many to many join table (the kind that accumulates in any mature relational schema) simply disappears as a separate table and becomes a relationship type in its own right, one that can carry its own properties the way the join table's extra columns used to. The direction of that relationship should encode dependency, not importance, and that convention is worth writing down explicitly somewhere every engineer will see it: six months later nobody remembers, and a reversed relationship produces a query that runs fine and returns exactly the wrong answer.
What can a relational schema structurally not hold?
A decision. Not the outcome of a decision recorded as a status flag on some other row: the decision itself, as a first class thing with a statement, a rationale, an approver, the evidence that produced it, and (critically) a link to whatever decision it later replaced. Relational schemas store the row that changed; they don't naturally store whyit changed or what it used to say. That's the gap that shows up as “institutional memory” problems in every large organization: the reasoning existed, it happened in a real conversation, and it was never captured as data because the schema had nowhere to put it.
Do you need a full cutover, or can both databases run together?
Most enterprise migrations start (and often stay) as a parallel system rather than a replacement. The relational database keeps handling what it's genuinely good at: transactional writes, simple lookups, and the reporting queries that were never the problem in the first place. The graph is built alongside it, fed from the same sources, specifically for the relationship heavy questions that were becoming unmanageable. A full cutover, if it ever happens, tends to arrive later and only for the specific workloads that actually belong there: not as a big bang replatform on day one.
What is the hardest part of a SQL to graph migration?
Entity resolution, almost without exception. The same real world concept (a person, an account, a product, a topic) arrives from source systems under several slightly different names within the first weeks of ingestion, and every query filtering on one variant silently returns a fraction of what it should. The failure is invisible, because the results still look plausible; nobody gets an error, they just gradually stop trusting the answers. This is as much a governance question as a technical one: someone on your team has to own the canonical vocabulary going forward, or the quality of the migration decays within a quarter regardless of how clean the initial cutover was.
Keep reading
Pillar
Neo4j Enterprise: production hardening →
Multi tenant isolation, erasure, and monitoring.
Pillar
7 failure modes that kill enterprise knowledge graphs →
The operational failures that actually sink projects.
Service
Enterprise knowledge graph consulting →
Ontology design before code, deployed in your VPC.
Case study
Optevo: AI native hybrid workspace →
Context aware AI grounded in a team's real work.