Ask which open-source memory engine to put behind your agent and you'll get sorted into a camp: graph people, vector people. In 2026 that sorting has stopped meaning anything. Mem0, Graphiti, and Cognee — the three developers actually line up against each other — all do hybrid retrieval now: semantic similarity, keyword matching, and graph traversal, blended. If you pick on "graph vs vector," you're choosing on a distinction the tools have already erased.

The distinction that survives is upstream of retrieval entirely. It's how much structure each engine commits at write time.

Why the write decides the read#

A memory system does two things: it stores what happened, and later it answers questions about it. The second is what you notice; the first is what constrains it. What you can retrieve is bounded by what you bothered to represent when you wrote — and the three engines make deliberately different bets about how much to represent.

You can't traverse a relationship you never stored, and you can't tell which of two facts is current if you stored them as equals. Retrieval can only surface the structure the write laid down.

So the honest comparison isn't a retrieval-quality shootout. It's a question of how much work each tool does before the question is ever asked, and what that buys you.

Mem0: commit little, write fast#

Mem0 sits at the light end. Its extraction is single-pass and ADD-only: it pulls facts out of a turn and stores them with minimal ceremony, then retrieves with multiple signals — semantic search, BM25 keyword matching, entity boosting. The payoff is real: the cheapest write path and the lowest latency of the three, which is exactly what a high-volume conversational agent wants when "remember the user's name and preferences" is most of the job.

The bill comes due on two kinds of question. Multi-hop reasoning — "what did the thing the user mentioned last week have to do with the project they just named" — has no stored path to walk, so it leans on similarity and can return something that looks right and isn't. And because facts are added rather than reconciled, a value that changed over time can leave two contradictory facts both sitting in the store, equally retrievable. For recent, mostly-flat recall, none of that matters. For history that reasons across itself, it does.

Graphiti: commit time, so facts can expire#

Graphiti spends more at write time to buy one specific thing: a sense of when. It builds a bi-temporal knowledge graph — every fact carries both valid-time (when it was true in the world) and transaction-time (when the system learned it) — and it invalidates superseded facts automatically. When a user moves from NYC to SF, Graphiti doesn't leave both facts true; it records that the first stopped being valid when the second began.

That is the failure mode Mem0's cheap writes court, addressed directly. The cost is a heavier ingest path and the operational reality that Graphiti expects a graph database underneath — Neo4j, FalkorDB, Neptune, or Kuzu. If your agent's memory is full of facts that change and it must never treat a stale one as current, that write-time investment is the feature, not overhead.

Cognee: commit structure, then distill it#

Cognee commits the most at write time. Its "cognify" step builds a typed ontology from what you ingest, and v1.2.0, released June 21, 2026, pushed further: auto-distillation inside its improve() workflow (batched curators and per-lesson writers, aimed at cutting duplicated documents), a proposals endpoint, and an inline skill-ingest API. The idea isn't just to store facts but to compress whole sessions into reusable lessons the agent can lean on later. (That release also renamed some env vars — LLM_MAX_TOKENS became LLM_MAX_COMPLETION_TOKENS — and disabled public registration by default, so read the notes before upgrading.)

The corollary most write-ups miss is operational, not qualitative. Cognee's default collapses the graph and vector layers onto a single Postgres, with graph and vector backends (Neo4j, Kuzu, Qdrant, LanceDB, Weaviate, Milvus) swappable if you outgrow it. That quietly breaks the assumption baked into the graph-memory pitch: that graph-structured memory requires standing up and operating a graph database. Here it doesn't. For a small team, "one Postgres you already run" versus "a Neo4j cluster you now own" changes the decision more than any retrieval benchmark will.

How to actually choose#

Match the write-time commitment to the questions you'll ask, and to what you're willing to operate:

The trap is choosing on the demo, where all three recall a planted fact and look identical. They diverge on the questions the demo doesn't ask — the multi-hop one, the "which is current" one, the one that arrives a month later. Those answers were decided at write time, before you ever typed the query. Pick the engine whose write commits to the questions you actually intend to ask. For the broader map of agent memory approaches, this is the axis worth carrying into every one of them.