Mem0 vs Graphiti vs Letta vs Cognee

Four Apache-2.0 agent memory layers, and in all four the repository you would install is not the artifact that produced the README’s numbers — Mem0 says so itself. What each data model can answer, which one enforces scope, and what you keep if you leave.

By Agentic AI Wiki 12 min read

All four of these projects are Apache-2.0, all four have five-figure star counts, and in all four the repository you would install is not the artifact that produced the numbers in the README. Mem0 says so outright: its 92.5 on LoCoMo comes from the managed platform, which "includes proprietary optimizations not available in the open-source SDK." Pick a memory layer on what its repository does unaided, and on how hard it is to leave — because the leaderboard is measuring somebody else's product.

At a glance

Star counts and versions below are as of late October 2026, read from each project's own repository.

ProjectStarsShape of the storeWhat the repo gives you alone
Mem067.8kLLM-extracted facts in a vector storeFull SDK and a self-hostable server; the benchmarked optimisations are platform-only
Cognee32.7kKnowledge graph built from documents and chatv1.6.1 runs keyless and local; graph-on-Postgres is a demo, production is licensed
Graphiti (Zep)32.2kBi-temporal entity graph with validity windowsThe whole framework — but it needs a graph database, and the reference servers have no auth
Letta25.3kAgent-owned memory blocks in its contextV1 server is on an archive branch; development moved to letta-code, default backend Letta Cloud
GitHub stars, agent memory layers, late October 2026 Horizontal bar chart of GitHub star counts read from each repository in late October 2026: Mem0 67.8 thousand, Cognee 32.7 thousand, Graphiti 32.2 thousand, Letta 25.3 thousand, and letta-code 3.7 thousand. GitHub stars (thousands) Mem0 67.8 Cognee 32.7 Graphiti 32.2 Letta 25.3 letta-code 3.7 20 40 60 letta-code is where Letta's development now happens; the 25.3k repo has archived its V1 server.
Mem0 leads on attention by more than 2×. The last bar is where Letta's development actually happens now.
Agent memory layers across four axes A four-by-four matrix rating Mem0, Graphiti, Letta and Cognee on self-host completeness, built-in scope enforcement, benchmark transparency and portability of what you keep. No project is strong on every axis: Graphiti is strongest on self-hosting and portability but publishes no benchmarks and ships reference servers without authentication; Cognee is strongest on scope enforcement and benchmark transparency but licenses its production graph path; Letta is weakest on self-hosting and portability. Where each one leans hardest Self-host completeness Scope enforcement Benchmark transparency Portability of exports Mem0 Medium SDK + server Weak user_id filter Medium numbers + caveat Medium facts + vectors Graphiti Strong whole framework Weak group_id, no auth Weak none published Strong graph + provenance Letta Weak V1 server archived Medium per agent Weak none published Weak harness-specific Cognee Medium graph path licensed Strong auth by default Strong caveats stated Medium Postgres rows Weak Medium Strong
Where each one leans hardest. No column has a strong cell in every row.

Four different things called memory

Four storage shapes behind the word memory Four panels. Mem0 extracts atomic fact strings and retrieves them from a vector index by similarity, with no relation between facts. Graphiti links entities with dated edges that are invalidated rather than deleted and traced back to a source episode. Letta keeps editable memory blocks inside the agent's own context, which the agent rewrites, and ingests no documents. Cognee ingests documents, code and chat into a dataset-scoped graph whose recall call names the dataset and requires an authenticated user by default. Mem0 prefers dark mode ships to Berlin owns three seats vector index retrieved by similarity no relation between facts Graphiti Alice owner_of AcmeCo valid 3 Mar - 14 Oct invalidated, not deleted entities, dated edges and a source episode Letta the agent's own context persona block human block agent rewrites them state, not a corpus no document ingestion Cognee documents, code, chat dataset graph recall(datasets=[...]) auth'd user by default scope is an argument on every call
The word "memory" is doing four jobs here, and the job decides what you can ask of it later.

Mem0 — extracted facts, retrieved by similarity

Mem0's model is the simplest to reason about and the cheapest to adopt: you hand it conversation turns, an LLM extracts short standalone facts, and those facts go into a vector store to be retrieved by similarity at prompt time. The install is pip install mem0ai or the npm SDK, the defaults are OpenAI's gpt-5-mini for extraction and text-embedding-3-small for embedding, and a Docker Compose server with a dashboard is in the repo.

What you give up is anything that depends on relations between facts. "What did we decide about pricing?" retrieves well. "Which of those decisions superseded which" does not, because supersession is a relation and the store holds points. Mem0's own numbers are also the clearest case of the gap this post is about: the README's table reports 92.5 on LoCoMo, 94.4 on LongMemEval and 64.1 on BEAM-1M, then states that these are platform scores and open-source users should expect "directionally similar gains but not identical numbers." That is an unusually honest footnote, and it means the comparison you actually want — library against library — has not been published by anybody.

Graphiti — a graph that knows when a fact stopped being true

Graphiti is the open-source framework underneath Zep, and it is the only one of the four whose data model directly answers the question most agent memory gets wrong. Facts carry validity windows; when a new episode contradicts an old one, the old edge is invalidated rather than deleted, and every entity and edge traces back to the source episode it came from. Retrieval combines semantic search, BM25 and graph traversal. If your agent needs to say "as of last week this was the owner, it changed on Tuesday," this is the model that can.

Two costs. First, infrastructure: Graphiti needs a graph database — Neo4j 5.26, FalkorDB 1.1.2, Amazon Neptune with OpenSearch Serverless for full-text, or Kuzu 0.11.2, which the project now marks deprecated and warns about at import. That is a real operational commitment next to Mem0's vector store. Second, the Zep relationship: the Community Edition of Zep itself is deprecated, its code moved to a legacy/ folder, and the getzep/zep repository states plainly that it "is not Zep's product or service" — it holds examples and integrations for Zep Cloud. The "sub-200ms at scale" figure belongs to the commercial product, not to the framework. Graphiti is genuinely complete as a library; Zep is a hosted service that happens to share a lineage with it.

Letta — memory the agent edits itself

Letta, formerly MemGPT, inverts the question. Instead of a store the harness queries on the agent's behalf, the agent owns editable memory blocks that live in its context and that it rewrites with tools as it learns. That is the right shape for a long-lived assistant whose self-description and working notes should change, and the wrong shape for a corpus: there is no document ingestion story here, because the unit is the agent's own state rather than your data.

Letta is also the project whose centre of gravity has moved furthest. The 25.3k-star letta repository has retired its V1 API server to an archive branch; active development is in letta-code (3.7k stars), an agent harness that tracks all context, memory blocks included, in git, and whose default backend on first launch is Letta Cloud. Running locally is offered and some features — remote machines, secrets — require signing in. If you are choosing Letta for the self-hosted stateful server you read about in 2025, check which repository and which branch that server is now in before you plan around it.

Cognee — a graph you build from documents, with tenancy on by default

Cognee is the one to read first if your memory is mostly content rather than conversation. Its four verbs are remember, recall, improve and forget; remember and recall take a dataset name, so scoping is a first-class argument rather than a filter you remember to pass. Since v1.0 the whole layer can sit on one Postgres instance covering relational metadata, PGVector and graph state, and v1.6.1 (24 September 2026) runs the default local path keyless, with a local GLiNER extractor and local embeddings — the only one of the four that needs no model provider to try.

It is also the only one that defaults to requiring an authenticated user: every /api/v1 call is multi-tenant unless you set ENABLE_BACKEND_ACCESS_CONTROL=false. And it is the most careful about its own evaluation. The README reports BEAM scores of 0.79 at 100K tokens and 0.67 at 10M, labels the second exploratory, and warns that the two settings use different conversations, ingestion models and retrieval-selection procedures so the scores are not directly comparable — while noting an open reproduction gap on the distributed 10M ingestion. The catch is in the storage story: Postgres as the graph store is described as a demo feature, with the production version a licensed product.

Cross-cutting comparison

Every number you would compare them on is self-reported

LoCoMo, LongMemEval and BEAM are the three benchmarks in play, and across all four projects there is no independent replication of any score. Mem0 publishes the most numbers and attributes them to its platform; Cognee publishes fewer and attaches the caveats itself; Graphiti publishes none, offering only a latency comparison against GraphRAG with no methodology; Letta publishes none. Worse, the sample sizes at the interesting end are small enough to swallow the differences: BEAM's 10M bucket is roughly 200 questions, so a reported 48.6% carries a 95% interval of about ±6.9 points on binomial counting error alone. A 3-point gap between two vendors at that scale is noise. A 15-point drop from 1M to 10M, which Mem0 reports, is not — and that drop is the finding worth taking from the whole leaderboard: all of these degrade sharply as the corpus grows, and contradiction resolution scores worst of the sub-skills.

Scope is an argument the caller passes, not a principal

In Mem0 the scope is user_id, passed to add and to search filters. In Graphiti it is group_id. In Cognee it is a dataset name, with sessions layered on top. In Letta it is the agent itself. In three of the four, nothing in the library checks that the caller was entitled to the scope it named — which is a design choice, not a bug, as long as something above it does. Graphiti is explicit about the consequence: its reference MCP and REST servers have no authentication and no prompt-injection protection, callers can access any group_id, and the project says they are not meant for untrusted networks. Cognee is the exception, defaulting to an authenticated user per call. If you are deploying any of these for more than one human, see memory scopes and tenancy — the failure is silent, because an embedding does not carry who wrote it.

The exit cost is the real differentiator

Ask what you keep if you stop paying, or if the project pivots. Graphiti gives you a graph in a database you already run, with provenance edges back to source episodes — the most portable artifact of the four. Cognee gives you Postgres rows, with the caveat that the production graph path is licensed. Mem0 gives you extracted fact strings plus embeddings, portable but lossy: the extraction decisions are gone. Letta gives you memory blocks tracked in git, portable in form but meaningless outside the Letta harness that interprets them. Two of the four have already moved their own centre of gravity once this year, which is the best available evidence about how durable any of these choices is.

When to pick which

SituationPickWhyWhat it costs you
Conversational personalisation, ship this monthMem0Lowest adoption cost, widest SDK surfaceNo relations; the published numbers are not the library's
Facts that change and must be datedGraphitiValidity windows and provenance are in the data modelYou run a graph database; reference servers need auth put in front
Documents and code as the memoryCogneeIngestion-first, dataset scoping, keyless local startProduction graph storage is a licensed path
One long-lived assistant that should changeLettaAgent-owned editable blocks, not a queried storeCheck which repo and branch; Cloud is the default backend
Multi-tenant from day oneCognee, or Graphiti behind your own gatewayOnly Cognee defaults to an authenticated principalEveryone else needs an enforcement layer you write

And one case for none of them: if your agent's memory requirement is "remember the five things the user told me earlier this session," a table with a user id and a LIMIT 5 is the right answer, and the write path is the part worth designing rather than the store.

FAQ

Is Zep's open-source version dead?

The Zep Community Edition is deprecated and its code has moved to a legacy/ folder; the getzep/zep repository now holds examples and integrations for Zep Cloud and states it is not Zep's product. Graphiti, the framework underneath, is actively maintained and Apache-2.0.

Can I trust the LoCoMo and LongMemEval scores?

Treat them as vendor claims. They are self-reported, unreplicated, graded by an LLM judge whose identity changes the result, and in LoCoMo's case partly solvable by a long-context model ingesting the whole dialogue — which makes the score a property of the backbone as much as the memory layer.

Which one needs the least infrastructure?

Cognee's default local path, which runs keyless with a local extractor and local embeddings, then Mem0 with a vector store, then Cognee on a single Postgres, then Graphiti with a graph database.

Do I need a graph at all?

Only if you will query relations or time. Graphs earn their operational cost when the agent must answer "what changed, and when" or traverse more than one hop; for similarity recall over short facts, a vector store is less to run and less to get wrong.

How should I actually evaluate these?

On your own corpus, with your own questions, including contradictions you planted deliberately — that sub-skill scores worst for everyone. See evaluating memory quality for the metrics, and evals, in plain words for why twenty cases you wrote beat a public leaderboard here.

Further reading

On this wiki:

Project sources: