---
title: "AI Agent Memory: Mem0 vs Zep vs Letta"
description: "A practical comparison of AI agent memory frameworks Mem0, Zep, and Letta, covering the LongMemEval benchmark and which one actually fits your constraints."
image: "https://foundrysoft.co/api/og?type=article&title=AI+Agent+Memory%3A+Mem0+vs+Zep+vs+Letta&cat=Comparisons&rt=12+min+read&au=Varun+Raj+Manoharan&dt=2026-07-29"
url: "https://foundrysoft.co/blog/ai-agent-memory-mem0-vs-zep-vs-letta"
---

Comparisons 2026-07-29 12 min read

# AI Agent Memory: Mem0 vs Zep vs Letta

A practical comparison of AI agent memory frameworks Mem0, Zep, and Letta, covering the LongMemEval benchmark and which one actually fits your constraints.

![Varun Raj Manoharan](https://foundrysoft.co/images/about/founder.webp)

Varun Raj Manoharan Founder & Principal Engineer

AI Agent Memory Mem0 Zep Letta LLM Agents

## Key takeaways

-   Most requests for 'agent memory' are actually asking for a bigger context window or document retrieval, and neither problem is solved by adding a memory framework.
-   Mem0 is a library, Zep is a temporal graph service, and Letta is a runtime that owns the agent loop, so choosing between them is choosing how much of your architecture you hand over.
-   Zep scores 63.8% on LongMemEval against Mem0's 49.0% in a direct comparison, but a benchmark score does not predict how either system performs on your own conversations.
-   Memory systems fail quietly in production through stale facts, contradictory updates, incomplete deletions, and the per-turn cost of running an LLM to decide what's worth keeping.

A team asks me to help them add memory to their agent, and half the time what they actually need is a bigger context window. Another chunk of the time they need retrieval over a document set that never changes based on what a user says to it. Real AI agent memory, the kind that recalls a fact from six months ago or notices that a preference changed since last week, is a narrower problem than either of those, and it's the one this post is actually about.

The three get conflated constantly, and the mix-up costs real engineering time, because the fix for each is different. A context window is bytes visible to the model on this call and nothing more. It resets the moment the call ends. Retrieval over documents is a search index over a static corpus, your product docs, your policy manual, whatever, and it doesn't change shape because a user told the agent their name. Memory about a user or a working relationship is the one that has to persist across sessions, update when facts change, and decide on its own what's worth keeping and what to let go of. If your requirement is "the agent should remember what I told it in our last conversation," you're in memory territory. If your requirement is "the agent should answer questions about our 400-page onboarding guide," you need retrieval, and a memory framework won't help you there.

## AI agent memory is not a context window or a retrieval index

The confusion is understandable because all three end up looking similar from the outside: text gets fetched and stuffed into a prompt before the model generates a response. The difference is in what decides what gets fetched and why it changes over time.

A context window has no opinion about relevance. Everything in it is in it because you put it there, and it stays until you take it out or the conversation ends. Retrieval over documents has an opinion about relevance, but it's a fixed opinion, computed once over a corpus that doesn't know who's asking. Memory is the one where the store itself is built from interactions, gets written to as a side effect of conversation, and has to be curated over time, because an agent that remembers everything forever isn't remembering, it's just accumulating a transcript.

That last distinction is where AI agent memory earns its name. A system with real memory can tell you a fact stated in March is different from what the same user said in July, can hold the newer one as current, and can still explain what changed if asked. Most retrieval systems have no mechanism for that at all. They don't track when a document was superseded unless you build that logic yourself.

This is where Mem0, Zep, and Letta live. There are other systems working the same problem, Graphiti, LangMem, and Cognee among them, and worth a look if none of these three fit. This post covers the three with the most production use and the clearest architectural differences from each other.

## Mem0, Zep, and Letta are not interchangeable

The three solve the same broad problem with genuinely different shapes, and picking between them is less "which is better" and more "how much of my architecture am I willing to hand over."

Mem0 is a library. You install it, you call it from inside whatever agent loop you already have, and it stores memories in a combination of vector, graph, and key-value storage depending on what you ask it to do. You hand it a conversation and it decides what's worth keeping, using an LLM call to extract facts rather than storing raw transcript. It has the largest community of the three by a wide margin, somewhere around 47,000 to 48,000 GitHub stars, and the broadest framework support, which matters if your agent already runs on LangGraph, CrewAI, or a custom loop and you don't want to rebuild it. Mem0 raised a $24M Series A, which is one signal the approach has commercial traction, not proof of technical superiority.

Zep is a service, and what it stores is a temporal knowledge graph built from the conversation rather than a flat memory list. Facts become nodes and edges with a time dimension attached, so the system can represent not just "the user prefers X" but "the user preferred X until this date, then switched to Y." That temporal structure is also what makes Zep the strongest fit for regulated environments: it holds SOC 2 Type 2, HIPAA, and GDPR certification, and in a comparison against four other systems in the space it was the only one to hold all three at once.

Letta is neither a library nor a passive store. It's an agent runtime, meaning it owns the loop that decides what the agent does next, and memory management is a first-class primitive inside that loop rather than something bolted on. The agent manages its own memory: it can read its own memory blocks, decide to rewrite them, and treat memory editing as an action available to it the same way calling a tool is. That makes Letta the natural fit for long-running autonomous agents that operate for extended stretches without a human in the loop, but it also means adopting it is not additive the way installing a library is. You're handing Letta the part of your architecture that decides what the agent does next.

## What integrating each one looks like

Mem0's basic pattern is add and search. You hand it a conversation turn, it extracts what's worth keeping, and later you query it with the current question rather than the whole history.

Python

Copy

```python
from mem0 import Memory

memory = Memory()

# Hand the exchange to Mem0 and let it decide what's worth keeping.
memory.add(
    messages=[
        {"role": "user", "content": "I'm allergic to shellfish, keep that in mind."},
        {"role": "assistant", "content": "Noted, I'll avoid shellfish in any recommendations."},
    ],
    user_id="user_42",
)

# On a later turn, pull back whatever is relevant to the current query,
# not the entire history.
relevant = memory.search(
    query="what should I avoid ordering at a seafood restaurant",
    user_id="user_42",
)
```

The extraction step is doing real work you don't see in this snippet. Somewhere behind `add`, an LLM call looks at the exchange and decides "allergic to shellfish" is durable and worth storing while the rest of the small talk isn't. That decision is opaque unless you go looking for it, which matters later when we get to auditing what a system remembers and why.

Letta inverts the relationship. Instead of your code calling a memory store, you hand Letta a persona and a set of memory blocks when you create the agent, and the runtime decides when to rewrite them as the conversation continues. Letta's client API moves faster than Mem0's and the exact method names shift between releases, so treat the shape below as illustrative and check current docs before you write against it.

Python

Copy

```python
# Illustrative shape only, confirm exact method names against current Letta docs.
from letta_client import Letta

client = Letta(base_url="http://localhost:8283")

agent = client.agents.create(
    memory_blocks=[
        {"label": "human", "value": "Name: Priya. Prefers concise answers."},
        {"label": "persona", "value": "A terse, technical support agent."},
    ],
    model="...",
)

# You send a message. The runtime, not your code, decides whether
# a memory block gets rewritten as a result.
response = client.agents.messages.create(
    agent_id=agent.id,
    messages=[{"role": "user", "content": "I'm allergic to shellfish too."}],
)
```

Notice what's missing compared to the Mem0 example: there's no separate `search` call. Retrieval isn't something you do, it's something the running agent does for itself as part of its own loop, because the loop belongs to Letta, not to your code.

Zep's shape sits between the two conceptually, closer to Mem0's in that you call it rather than hand it your loop, but the underlying store is a graph rather than a set of discrete memory records. You add data to a user's graph as the conversation happens, and query time involves asking the graph for relevant nodes and edges rather than a flat similarity search. The exact call signatures depend on the SDK version, so I'm describing the shape rather than showing code I'm not certain is current: add turns or facts to a session-scoped graph, then query that graph for context before generating a response, with the temporal ordering of facts available to you as a first-class part of the result rather than something you have to reconstruct from timestamps yourself.

## The LongMemEval number, and what it doesn't prove

In a direct comparison, Zep scored 63.8% on LongMemEval against Mem0's 49.0%. That's a real gap, not a rounding difference, and Zep also reported a latency reduction of up to 90% in the same comparison. It's a reasonable data point if you're choosing between the two and have nothing else to go on.

What it isn't is a guarantee about your own agent. A benchmark like this evaluates a fixed set of question types, phrased however the benchmark's authors phrased them, against conversations that were curated or synthesized for the purpose of testing memory. It doesn't know your users' vocabulary, doesn't know how your product accumulates state over a session, and doesn't know how you've written the retrieval prompt that consumes whatever the memory system hands back. Two systems that differ by fourteen points on a benchmark can land much closer, or further apart, once you swap in your own data and your own question patterns.

There's also a version of this number that gets misread as "Zep's graph approach beats vector storage." Maybe it does, for the kinds of temporal and multi-hop questions LongMemEval includes. But the honest reading is narrower: on this benchmark, with these questions, Zep's approach scored higher than Mem0's. That's worth knowing before you pick a tool. It isn't a substitute for testing both against a sample of your own conversations before you commit either one to production, and given how much the gap could move on your data, that test is worth doing before the benchmark number decides anything for you.

## A decision framework for agent memory, organized by constraint

The product comparison is interesting, but most teams don't actually get to pick freely. Something else in the environment usually picks first.

If you're handling regulated data, health records, financial data, anything that puts HIPAA or GDPR in the room, the certification question isn't optional. Zep is the one of the three with SOC 2 Type 2, HIPAA, and GDPR certification, and if compliance already flagged this as a requirement, that narrows the field before you've evaluated anything else about accuracy or latency.

If self-hosting matters to you, the architectural shape changes what "self-hosting" even means for each option. A library has no separate hosting question, because there's nothing to host beyond whatever database you point it at yourself. A managed service and a runtime each have their own deployment story, and those offerings change over time, so confirm the current self-hosting options directly against each vendor's docs rather than assuming last year's answer still holds.

If you already have an agent loop you like, built on LangGraph or something custom, adopting Letta means giving up part of that loop, since Letta wants to own it. Mem0 and Zep both sit underneath whatever loop you already run, because neither is trying to be the loop. That's a real architectural cost to weigh against Letta's advantage for autonomous, long-running agents that don't have a human checking in every few turns.

If memory needs to be inspectable and editable by a human, not just by the agent, look at how each system exposes what it's storing. Letta's memory blocks are explicit and named, which makes them easy to read and hand-edit. Zep's graph is inherently browsable as entities and relationships, which tends to make "what does the system think it knows about this user" a query you can actually run. Mem0's extraction step is closer to a black box: the LLM decides what's worth keeping, and getting a clear picture of the full memory set means querying it directly rather than reading a structure that was designed to be legible at a glance.

If you need to explain to a user why the agent remembered something, the same distinction applies from the other direction. A graph with explicit relationships and timestamps gives you a real answer to "why do you think that." An extraction pipeline that folds a decision into a single stored sentence gives you less to point to, even if the underlying recall is accurate.

A shorthand you'll hear a lot in this space: Mem0 for consumer-facing personalization, Letta for autonomous agents, Zep for regulated industries. It isn't wrong, and it's a fair starting heuristic, but it compresses the constraints above into three words each. The constraints are the actual reasoning; the shorthand is just what's left after you've already done that reasoning once.

## What breaks after you ship

None of the three solve the parts of memory that only show up once real users are hitting the system.

Memory goes stale in ways that are easy to miss during a demo and obvious in production. A user tells the agent they work at one company, changes jobs eight months later, and never explicitly tells the agent the old fact is wrong, they just start talking as though the new one is true. Something has to decide when an unconfirmed old fact should stop being served as current, and none of these systems does that automatically just because time has passed. You either build a staleness policy or you live with an agent that confidently repeats something that stopped being true.

Contradictions are a related problem but not the same one. A user says "I don't eat meat" in March and "grab me a burger" in September, and now the system holds two facts that can't both be current. A temporal graph like Zep's has a natural place to put both, with time attached, so you can reason about which one is newer. A flat memory store has to make that same decision at write time or leave the contradiction sitting there for whichever record retrieval happens to surface first.

Deletion is the one people discover latest, usually when a user asks the agent to forget something, or when a compliance request forces the question. The test isn't whether you can delete a record from wherever you thought the fact lived. It's whether that deletion actually reaches every place a derived version of that fact might have landed: the primary store, any vector index built from it, any graph edges connected to it, any cached summary generated from it before the deletion request came in. A partial deletion that leaves a trace in a vector index is still a real problem even if the primary record looks clean.

And extraction has a cost that's easy to underestimate before you've run it at volume. A system like Mem0's, where an LLM decides what's worth keeping from every exchange, means an extra model call on every turn, or close to it, before the user ever sees a response. That's added latency and added spend that doesn't show up in a demo with five test conversations but shows up clearly once you're running thousands of turns a day. A system that stores raw text and defers the "what matters" decision to query time shifts that cost instead of removing it, so it's worth measuring where in your pipeline you actually want to pay it.

Before you commit to any of the three, write down what happens the day a user asks the agent to forget something they told it. Trace which store the request has to reach, what "deleted" actually means in that store, and whether you can prove after the fact that it worked. If you can't answer that today, it's a better use of an afternoon than another round of comparing benchmark scores, because the constraint that decides which of these tools fits your project usually isn't the one on the leaderboard.

#### Related reading

[Context Engineering for AI Agents: Managing the Context Window in Production

Context engineering for AI agents is now the skill that decides whether a long-running agent works, and it means managing context rot, compaction, and the agent context window instead of writing a better prompt.

Context Engineering AI Agents Context Window

](https://foundrysoft.co/blog/context-engineering-ai-agents-production)

#### Next Article

[

The AI Coding Tools Stack: Why Teams Run Cursor, Claude Code, and Copilot Together

](https://foundrysoft.co/blog/multi-tool-ai-coding-stack-cursor-claude-code-copilot)

Available for new projects

## Let's build something great.

Have a project in mind? We are an elite software and AI development studio ready to bring your ideas to production. Let's talk about your roadmap.

Start a Project [See our work](https://foundrysoft.co/work)

```json
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "FoundrySoft",
  "url": "https://foundrysoft.co",
  "logo": "https://foundrysoft.co/logo.svg",
  "description": "FoundrySoft builds production-grade software and AI systems for US companies, from an India-based team of senior engineers.",
  "sameAs": [
    "https://github.com/foundrysofthq",
    "https://www.linkedin.com/company/foundrysoft",
    "https://www.instagram.com/foundrysoft/"
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "FoundrySoft",
  "url": "https://foundrysoft.co"
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "AI Agent Memory: Mem0 vs Zep vs Letta",
  "description": "A practical comparison of AI agent memory frameworks Mem0, Zep, and Letta, covering the LongMemEval benchmark and which one actually fits your constraints.",
  "url": "https://foundrysoft.co/blog/ai-agent-memory-mem0-vs-zep-vs-letta",
  "mainEntityOfPage": "https://foundrysoft.co/blog/ai-agent-memory-mem0-vs-zep-vs-letta",
  "image": [
    "https://foundrysoft.co/images/blog/ai-agent-memory-mem0-vs-zep-vs-letta.webp"
  ],
  "datePublished": "2026-07-29",
  "dateModified": "2026-07-29",
  "keywords": "AI Agent Memory, Mem0, Zep, Letta, LLM Agents",
  "author": {
    "@type": "Person",
    "name": "Varun Raj Manoharan"
  },
  "publisher": {
    "@type": "Organization",
    "name": "FoundrySoft",
    "logo": {
      "@type": "ImageObject",
      "url": "https://foundrysoft.co/logo.svg"
    }
  }
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://foundrysoft.co/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Blog",
      "item": "https://foundrysoft.co/blog"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "AI Agent Memory: Mem0 vs Zep vs Letta",
      "item": "https://foundrysoft.co/blog/ai-agent-memory-mem0-vs-zep-vs-letta"
    }
  ]
}
```
