Manage risk
Identity resolution over shared attributes
Every company above a certain age has the same customer three times: once from signup, once from support, once from an acquisition's CRM. The records disagree; what they share — an email, a phone, a card — is how you find them.
The model
The shape of the problem
Make each source record a node and each identifying attribute — email, phone, address, payment method — its own node. Records that share an attribute are now literally connected, and a duplicate cluster is a connected component you can walk with a variable-length path. Matching logic becomes visible structure instead of a tangle of LIKE clauses.
Match transitively, not just pairwise
A shares an email with B; B shares a phone with C. Pairwise SQL matching finds A–B and B–C and misses that all three are one person. A variable-length traversal across shared attributes finds the whole chain in one query.
Keep the evidence
Instead of destructively merging rows, link records to a golden Person node with MERGE. Every match stays inspectable — which attributes connected these records, and when — so a wrong merge is reversible and an auditor can see the reasoning.
Search the messy parts
Names and addresses rarely match exactly. Built-in full-text indexes with BM25 ranking find candidate records despite typos and variant spellings; the graph then confirms or rejects the candidate through harder identifiers.
MATCH (seed:Record {id: $id})
MATCH path = (seed)-[:HAS_EMAIL|HAS_PHONE|HAS_CARD*1..6]-(dup:Record)
WHERE dup <> seed
RETURN DISTINCT dup.source, dup.name,
[n IN nodes(path) WHERE NOT n:Record | n.value] AS viaQuestions
Identity resolution, asked directly.
Why not just do this in SQL?
Pairwise matching works in SQL. Transitive matching — A matches B matches C — needs recursive self-joins that grow with cluster size. In a graph the cluster is already connected; you walk it.
How do fuzzy matches work?
Full-text indexes with BM25 ranking handle the approximate side — names, addresses, typos. The graph handles the exact side — shared emails, phones, cards. Real pipelines use the first to propose and the second to confirm.
Is merging destructive?
It doesn't have to be. The golden-record pattern links source records to a Person node and keeps every original intact, so a bad merge is one DELETE of a relationship, not a data-recovery exercise.
Can this run continuously?
Yes. New records MERGE their attribute nodes on ingest, which connects them to any existing cluster immediately — resolution becomes a property of the write path rather than a quarterly project.
What about consent and audit?
The graph records why two records were linked — the shared attributes are the edges. The console adds an audit log of every administrative change on the instance itself.
How do I load records from many systems?
Connectors cover the usual sources — Postgres, BigQuery, Snowflake, S3/GCS/Azure, Kafka — and idempotent MERGE loads mean re-running an import can't create the duplicates you're trying to remove.
Related solutions
Manage risk
Fraud detection
Fraud hides in relationships — shared cards, devices and addresses. Model transactions as a graph and expose rings that row-based queries can't reach.
Read moreIncrease revenue
Recommendations
People who bought this also bought — computed live from the purchase graph, not from a nightly batch. Collaborative filtering as a two-hop Cypher traversal.
Read moreBuild with AI
Knowledge management
Documents, people, systems and decisions, connected and queryable. Full-text search finds the node; the graph explains its context.
Read moreStart now
~98.7%
token efficiency at 2,000 entities — see the footnotes above
Put your first graph up in a minute.
A free instance takes about a minute and no card. Write two MERGE statements, read them back, and you have a living graph — with provenance on every fact.
First-graph path
LiveCreate a free instance
No card. Ready in about a minute.
Connect your driver
bolt+ssc:// URI into the driver you already use.
Write two MERGEs
That's the entire shape of agent memory.
Point an agent at it
One MCP config block. No integration code.