{"slug": "mem0-vs-zep-vs-langchain-memory-vs-letta-which-one-actually-remembers", "title": "Mem0 vs Zep vs LangChain Memory vs Letta: Which One Actually Remembers?", "summary": "A developer's comparison of AI memory tools Mem0, Zep, LangChain Memory, and Letta reveals that real memory requires conflict resolution, not just retrieval. Mem0 uses a two-stage LLM call to add, update, or delete facts, while Zep's Graphiti engine uses bi-temporal graphs to track changes over time. LangChain's memory classes are building blocks that leave conflict resolution to the developer.", "body_md": "Most \"AI memory\" demos are a vector store with a marketing label. You embed every message, cosine-search the top-k on the next turn, and call it memory. It works until turn 40, when the agent confidently tells a user their favorite color is blue because that's what came back highest-ranked — even though they corrected it three messages later.\n\nReal memory isn't retrieval. It's deciding what's still true. That distinction is why four very different architectures — Mem0, Zep, LangChain's memory classes, and Letta (formerly MemGPT) — all claim the same territory but solve almost none of the same problems. Here's what each one actually does under the hood, where it breaks, and which one you should reach for.\n\n`ConversationBufferMemory`\n\n, `ConversationSummaryMemory`\n\n, `ConversationKGMemory`\n\n, `VectorStoreRetrieverMemory`\n\n— these are building blocks, not a memory service. You own the extraction logic, the storage schema, and every decision about what gets kept or discarded. `ConversationSummaryMemory`\n\nre-summarizes the whole history on every turn, which means cost and latency grow with conversation length even though the output size doesn't. `ConversationKGMemory`\n\nextracts triples but has no mechanism to invalidate a triple once a new fact contradicts it — old and new coexist in the graph, and retrieval has no way to prefer one.\n\nThis is fine if you want full control and are building something bespoke on top of LangGraph's checkpointing. It's the wrong choice if you want memory to just work, because \"just work\" is precisely the part LangChain leaves as an exercise for you.\n\n**Use it when:** you're already deep in LangGraph, you have specific extraction logic you don't want a black box making decisions about, and you're willing to build conflict resolution yourself.\n\nMem0's core loop is a two-stage LLM call. First, an extraction pass pulls candidate facts out of a message (\"user prefers dark mode,\" \"user is allergic to shellfish\"). Second — and this is the part most memory layers skip — a second LLM call compares each candidate against the *existing* memories for that user and decides: ADD (net new), UPDATE (same entity, changed value), DELETE (contradicted), or NOOP (already known). That decision is what stops the shellfish-allergy memory from sitting next to a stale \"user eats shrimp regularly\" memory forever.\n\n``` python\nfrom mem0 import Memory\nm = Memory()\nm.add(\"I used to like coffee but I've switched to tea\", user_id=\"u1\")\n# extraction: {preference: tea}, conflict check against\n# existing {preference: coffee} -> UPDATE, not ADD\n```\n\nMemories are stored as embeddings in a pluggable vector store (Qdrant, Chroma, pgvector, Weaviate) with metadata, and Mem0 added a graph layer (Neo4j-backed) for relationship queries — \"who does the user report to\" style facts that a flat vector store handles badly. Addition is async by default, so it doesn't block your response path, which matters if you're calling `add()`\n\nafter every turn in a latency-sensitive chat app.\n\nThe honest tradeoff: the conflict-resolution LLM call is an extra hop with extra cost and extra latency on the write path, and if your extraction prompt is too aggressive you'll get memory bloat — hundreds of low-value \"facts\" that dilute retrieval quality. Mem0 gives you knobs (custom extraction prompts, memory-type separation) but you still have to tune them.\n\n**Use it when:** you have a multi-session, multi-user product (support bot, personal assistant, CRM copilot) where facts genuinely change over time and you need automatic reconciliation instead of a growing pile of contradictions.\n\nZep's differentiator is Graphiti, its temporal-graph engine. Instead of choosing between \"keep the old fact\" or \"overwrite it,\" Zep timestamps edges with both event time and ingestion time (a bi-temporal model) and marks superseded facts as invalid rather than deleting them. Ask Zep \"where did the user work in 2023\" and it can answer correctly even after the user has since changed jobs, because the graph retains history instead of collapsing to a single current value.\n\nThis is genuinely different from Mem0's ADD/UPDATE/DELETE model — Zep never deletes, it invalidates, which means you get an audit trail for free. That's valuable for compliance-sensitive domains but it's overkill if you only ever care about the *current* state of a fact and don't need to reason about when it changed.\n\n**Use it when:** you need point-in-time correctness — support timelines, longitudinal user profiles, anything where \"what did we believe was true at time X\" is a real query, not just \"what's true now.\"\n\nLetta flips the architecture entirely. Instead of an external pipeline deciding what to remember, the LLM agent itself gets memory-editing functions (`core_memory_append`\n\n, `core_memory_replace`\n\n, `archival_memory_insert`\n\n) as tools it can call mid-conversation. Context is split into an OS-style hierarchy: core memory (small, always in the prompt, directly editable), and archival/recall memory (external, paged in via search when relevant). The agent decides, at inference time, what's worth writing down and what's worth paging back in.\n\nThe upside is nuance — the agent can decide \"this is important enough for core memory\" versus \"this is archival trivia\" based on actual conversational context, not a fixed extraction heuristic. The downside is cost and predictability: every memory operation is now an extra tool call inside the agent's own reasoning loop, which adds latency and makes memory writes non-deterministic across runs. Debugging \"why didn't it remember X\" means inspecting the agent's tool-call trace, not a pipeline log.\n\n**Use it when:** you're building a long-running autonomous agent (not a request/response chatbot) where memory management is itself part of the task the agent should reason about — not a side effect you want abstracted away.\n\n| Need | Reach for |\n|---|---|\n| Full control, already on LangGraph | LangChain memory primitives |\n| Multi-user product, facts change, want automatic reconciliation | Mem0 |\nNeed to know what was true when, audit trail |\nZep |\n| Autonomous long-running agent, memory as part of the task | Letta |\n\nThe question to ask before picking any of these isn't \"which has the best retrieval.\" Retrieval is the easy 20%. It's \"who decides when a memory is wrong, and how do they find out.\" A vector store with no conflict resolution will happily retrieve a stale fact with high cosine similarity and hand it to your agent with total confidence. That's not memory — that's a very expensive way to remember things incorrectly.", "url": "https://wpnews.pro/news/mem0-vs-zep-vs-langchain-memory-vs-letta-which-one-actually-remembers", "canonical_source": "https://dev.to/mukesh_13/mem0-vs-zep-vs-langchain-memory-vs-letta-which-one-actually-remembers-2j47", "published_at": "2026-08-26 20:03:18+00:00", "updated_at": "2026-08-26 20:20:22.893886+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-tools", "ai-agents", "developer-tools"], "entities": ["Mem0", "Zep", "LangChain", "Letta", "Graphiti", "Neo4j", "Qdrant", "Chroma"], "alternates": {"html": "https://wpnews.pro/news/mem0-vs-zep-vs-langchain-memory-vs-letta-which-one-actually-remembers", "markdown": "https://wpnews.pro/news/mem0-vs-zep-vs-langchain-memory-vs-letta-which-one-actually-remembers.md", "text": "https://wpnews.pro/news/mem0-vs-zep-vs-langchain-memory-vs-letta-which-one-actually-remembers.txt", "jsonld": "https://wpnews.pro/news/mem0-vs-zep-vs-langchain-memory-vs-letta-which-one-actually-remembers.jsonld"}}