Skip to content
Contextely

Memory graph

A graph where every line has a source

Relations are extracted in the same model call that writes the summary, so the graph costs nothing beyond the tokens to name them.

What comes back

Triples, each naming the memory that asserted it

An agent answering from a graph is otherwise presenting an inference as a fact, with nothing to check it against.

Seeded from a real search

A walk starts from the memory objects a normal retrieval ranked, which have already been checked against who is asking. The graph itself needs no vectors, which is the largest recurring cost a product like this can take on and one we simply do not.

Bounded, so it stays fast

Depth and the number of relationships followed from any one thing are both capped, so a query costs the same whether your graph holds a thousand relationships or a billion. The thing that makes graphs slow is one entity everything connects to, and that is skipped by how connected it is rather than discovered halfway through.

depth cappedfan-out cappedcost independent of size
POST /api/v1/graph/search
{
  "triples": [
    {
      "subject": { "label": "Northwind", "kind": "entity", "grounded": true },
      "predicate": "renews",
      "object":  { "label": "2026-11-30", "kind": "entity", "grounded": false },
      "depth": 1,
      "asserted_by": "a3f1c2e8-..."
    }
  ],
  "stats": { "withheld_for_entitlement": 4, "truncated": false }
}

The architecture

One Postgres. No vector service, no graph engine.

This is the part a self-hosting team is actually weighing, so it is worth being specific about.

A plain edge table

Two tables and an index. No extension, so the schema applies to any Postgres you already run, and nothing fails to install on a database that is missing something.

One bill, not three

A memory layer that needs a relational database, a vector service and a graph engine is three services to run, three to secure and three to pay for. The cheapest graph store is the Postgres you are already paying for.

Semantic search stays optional

Ranking is term overlap unless you name an embedding model. There is no default model and nothing to install, so a deployment that configures nothing takes the same code path it always did.

Your own words

Ground it in the nouns your company already has

Upload a vocabulary and extracted things are matched against it, so you can tell which ones you recognise.

What it does

Turtle, N-Triples, or a plain JSON list for a vocabulary that never was RDF. A match records the term’s stable identifier on the thing and marks it grounded, which the graph colours by.

What it is not

It is a lookup, not a reasoner. No axioms are evaluated, cardinality and disjointness are ignored, and nothing is inferred that your records did not say. Uploading an OWL file gets you the terms and not the restrictions.

Connect one source. The graph builds itself.

Relations come out of the condensation that was happening anyway, so there is nothing extra to turn on.