3 min read
When a graph database beats SQL: turning call logs into a relationship map
Call data is a relationship problem. Why Neo4j answers who-talks-to-whom questions better than SQL joins, and how to add grounded AI insights on top.

Short answer: use a graph database when your questions are about relationships: who is connected to whom, through what, and how often. Call data is a clear example. "Everyone this contact reached last month, and who they called next" takes a chain of self-joins in SQL but a single traversal in a graph database like Neo4j. If your questions are mostly totals, averages and filters over rows, stay with SQL.
I built a call intelligence pipeline that makes this choice, so here is how to tell which side of the line your data is on.
Why is call data a relationship problem?
A call platform emits events: caller, callee, duration, a recording link. Stored as a table, that is one row per call, which is perfect for questions like "how many calls did we take on Tuesday?"
The questions that actually matter to a sales or support team are different:
- Who are the most connected contacts on this account?
- Which people only ever reach us through one colleague?
- How did this lead come to us, and through which chain of calls?
Each of those is a question about paths between entities. A row-per-call table answers them badly.
SQL or a graph database: how do you choose?
| Your typical question | Better fit |
|---|---|
| How many, how long, what average, per day or per agent | SQL |
| Filter, group and aggregate over a fixed schema | SQL |
| Who is connected to whom, and how | Graph |
| Paths of unknown length, like "friends of friends" | Graph |
| Patterns across a network, like central or isolated contacts | Graph |
The line is not about data size. It is about the shape of the question. Once a query needs "join this table to itself again, as many times as it takes", a graph is the more natural tool.
What does the graph model look like?
In my pipeline, people, phone numbers and calls become nodes, and the links between them become edges. A call is connected to the number that made it and the number that received it, and numbers are connected to the person they belong to.
With that shape, "everyone this contact reached last month" is a short Cypher query that walks the edges, rather than a stack of joins that gets slower and harder to read with every hop.
What is the hardest part?
Identity resolution. The same person shows up as several numbers, in several formats, with and without country codes. Write those straight into the graph and one contact becomes five disconnected nodes, and every relationship query after that is quietly wrong.
The fix is to normalise numbers and resolve identities before anything is written to the graph. It is unglamorous work, and it decides whether the graph is useful at all.
Where does AI fit in?
After the graph, not instead of it. The pipeline runs Cypher queries to establish facts first: connection counts, frequencies, reach. Only then does an LLM read those structured results and write a readable summary.
That order matters. An LLM summarising facts the graph has already established is grounded. An LLM reading raw call events is guessing. Keeping the model on the summarising side of the pipeline is what keeps the insights trustworthy.
How is the pipeline put together?
- Webhook ingest: call events arrive at an n8n webhook as they happen.
- Metadata extraction: caller, callee, duration and recording details are pulled out and normalised.
- Graph modelling: entities and relationships are written into Neo4j.
- Graph queries: Cypher surfaces connection patterns, frequency and reach.
- AI insight generation: an LLM turns the query results into readable insights.
It runs continuously, from the moment a call ends to an updated picture of the account. The full workflow is on GitHub.
Frequently asked questions
- When should I use a graph database instead of SQL?
- When your main questions are about relationships: who is connected to whom, through what, and over paths of unknown length. For totals, averages, filters and grouping over a fixed schema, a relational database is usually the better fit.
- What is Neo4j good for?
- Data where the connections matter as much as the records, such as call networks, fraud rings, recommendations and organisational charts. Queries that would need many self-joins in SQL become short traversals in Neo4j's Cypher query language.
- How do you stop an LLM from inventing insights from data?
- Establish the facts first with ordinary queries, then give the model only those structured results to summarise. A model summarising facts a database has already established is grounded; a model reading raw events is guessing.