Agent Memory Systems and Knowledge Graphs: Letta, Mem0, Graphiti, and Cognee
Code Pointer
SubscribeSign in
Agent Memory Systems and Knowledge Graphs: Letta, Mem0, Graphiti, and Cognee<br>Design · A close look at four approaches to long-term agent memory, from text blocks to temporal graphs
Yongkyun<br>May 28, 2026
10
Share
Four popular agent-memory libraries each pick a different answer to the same design question. How should an agent remember things across sessions? Letta edits plain text blocks and files. Mem0 keeps a vector store with entity hints. Graphiti indexes facts as time-stamped relationships. Cognee runs an entity extraction pipeline.<br>Knowledge graphs store facts as typed relationships between entities. Obsidian built a million-user product on bidirectional note links navigable as a graph. Karpathy’s LLM Wiki proposed having an LLM build a persistent knowledge base from scratch. Graph structure could let you traverse connections across facts rather than just match by similarity. But a growing number of practitioners argue files alone work well enough in practice, and specialized graph tooling adds complexity without proportional benefit. We line the four up from least graph to most and trace two concerns through each one. Do related facts get pulled back together, and how do fact changes get handled?
Letta is a full agent framework that runs the agent for you. Mem0, Graphiti, and Cognee are memory layers you bolt onto your own agent. All four run paid cloud services on top of their OSS (Letta Inc., Mem0 Inc., Zep, Topoteretes), each with features beyond the OSS. This post covers the open-source versions.<br>Letta (MemGPT): self-editing text blocks
Letta uses no graph. Memory is split into tiers the agent manages itself. Memory blocks stay in context permanently. Each is a labeled text field with a fixed character limit the LLM reads and edits on every turn. Outside that sit archival memory searched by vector on demand, the recall message history, and an optional filesystem surface for uploaded docs.
The agent edits its own memory with tool calls. The edit surface is a handful of functions: core_memory_replace, memory_replace, memory_insert, memory_apply_patch, and memory_rethink. Retrieval is agent-driven too, through archival_memory_search and conversation_search plus filesystem open_files and grep_files.<br>core_memory_replace is the simplest of those edit-surface functions.<br>functions/function_sets/base.py:263-280<br>def core_memory_replace(agent_state, label, old_content, new_content) -> str:<br>"""Replace the contents of core memory. To delete memories, use an empty string for new_content."""<br>current_value = str(agent_state.memory.get_block(label).value)<br>new_value = current_value.replace(str(old_content), str(new_content))<br>agent_state.memory.update_block_value(label=label, value=new_value)<br>return new_value
The update is a plain string swap on block text, with no structure tracking what changed or when. Whether an outdated fact gets replaced depends entirely on the LLM noticing the contradiction and calling the function. Letta also ships sleeptime agents (letta/groups/sleeptime_multi_agent_v*.py), a background loop that consolidates and rewrites blocks between turns, so memory can change outside a live interaction. The mechanism is still self-editing text.<br>To walk through the full flow end to end, say you give the agent a human block that reads “Lives in Boston.” You send “I moved from Boston to SF.” The agent reads its own block, sees the contradiction, and calls core_memory_replace to swap “Boston” for “SF” in the text. When you later ask “Where do I live?”, there is no retrieval step because that block is always in context and now reads “Lives in SF.” Boston is gone with no record it was ever there. The flow hangs on the model noticing the contradiction and choosing to overwrite. Nothing fires if it does not.<br>Letta’s “Is a Filesystem All You Need?” post (Aug 2025) dumped LOCOMO (a multi-session dialogue recall benchmark) conversation transcripts into files attached to a plain agent and scored 74.0%, above the 68.5% for Mem0’s graph variant (arXiv 2504.19413, Apr 2025). Letta argues that agents are post-trained to be good at iterative file search, so specialized memory systems add little.<br>Mem0: graph out, entity linking in
Mem0 started with an optional graph layer and then removed it from the v3 open-source rewrite. That deletion is OSS-only. Mem0’s hosted Platform still lists graph memory and time-based decay as features.<br>Graph memory arrived in PR #1718 as an opt-in layer, then grew through 2025 to store that graph in any of five graph databases, Neo4j, the in-memory Memgraph, the embedded Kuzu, AWS’s managed Amazon Neptune, and Apache AGE, a graph extension for Postgres. The v3 pipeline removed the module in commit a488e190 (PR #4805, merged Apr 14 2026).<br>Entity linking replaced graph memory. Entities are pulled out with spaCy rather than an LLM and stored in a parallel {collection}_entities...