Agents

Mem0 vs Letta vs Zep

Mem0, Letta, and Zep are agent-memory products. Each stores facts an agent can retrieve on a later turn. They differ on how memory is shaped (extracted memories, in-context blocks plus archival search, or a temporal knowledge graph) and on what "forget" means (rank decay, developer delete, or fact invalidation).

Updated · Part of What is agent memory?

Three shapes of agent memory

Agent memory is durable, queryable state across turns: messages, retrieved facts, and tool results. A context window is not memory. A JSON file the app rewrites by hand is not a product. These three products are different answers to the same job.

Mem0: extracted memories, decay, expiration, delete

Mem0 extracts memories from conversations and searches them later. Memory Decay is an opt-in, per-project, search-time ranking bias on v3 search: recently accessed memories are boosted (up to about 1.5x) and idle ones are dampened (floor about 0.3x). Decay never deletes or filters a candidate out. Memory Expiration hides a memory after a date you set; the row stays stored. Delete removes it. Docs: https://docs.mem0.ai/platform/features/memory-decay and https://docs.mem0.ai/platform/features/memory-expiration

Letta: memory blocks, archival search, sleep-time agents

Letta agents persist system prompt, memory blocks, messages, and tools in a database. Memory blocks are strings pinned into the context window; agents edit them with memory tools, and developers can attach, detach, or share blocks. Archival memory is a semantically searchable store agents insert into and search; agents cannot easily modify or delete archival passages (developers can via the SDK). Sleep-time agents run asynchronously to reorganize in-context memory. Docs: https://docs.letta.com/guides/agents/memory and https://docs.letta.com/v1-sdk/memory/archival-memory/

Zep: temporal context graphs

Zep Cloud stores user context as a temporal Context Graph. Facts are edges with valid_at and invalid_at windows so a later preference can invalidate an earlier one without erasing history. Episodes are the raw sources; derived nodes and edges keep episode associations. Deleting an episode removes a derived fact only when no remaining episode supports it. Zep does not expire context on a default time schedule; retention policies and explicit deletes do. Docs: https://help.getzep.com/facts , https://help.getzep.com/context-retention.md , https://help.getzep.com/agent-memory-solution.md

How to choose

Pick from the forget policy and the data shape, not from a leaderboard this page did not run.

  • Pick Mem0 when you want extracted memories and search-time recency bias without deleting rows.
  • Pick Letta when the agent should edit in-context blocks, search an archive, and optionally run a sleep-time memory agent.
  • Pick Zep when facts have time bounds, provenance to source episodes, and invalidation instead of silent overwrite.

Last reviewed

Facts on this page were checked against vendor documentation on 2026-10-28. Product surfaces move; treat version names and APIs as directional and follow the official links in Related.

Mem0 vs Letta vs Zep (last reviewed: Oct 2026)

Mem0 vs Letta vs Zep (last reviewed: Oct 2026)
Mem0LettaZep
What it storesExtracted memories you searchIn-context blocks plus archival passages plus messagesEpisodes, entity nodes, and time-stamped fact edges
How retrieval worksSearch API; v3 search can apply decayBlocks are always in prompt; archive is tool searchContext Block from the graph; optional graph search tools
What "forget" meansDecay re-ranks; expiration hides; delete removesDeveloper delete of archival passages; agents rarely delete archiveInvalidate a fact; delete an episode; retention policy
TimeAccess history and optional expiration datesPersisted messages; not a temporal graph of factsvalid_at / invalid_at / created_at / expired_at on facts
Best forApp memory layer with opt-in recency rankingStateful agents that edit their own working memoryUser context that changes and must stay auditable
Official docshttps://docs.mem0.ai/platform/features/memory-decayhttps://docs.letta.com/guides/agents/memoryhttps://help.getzep.com/agent-memory-solution.md

Where Pixeltable fits

Use Pixeltable when agent memory should be ordinary tables you query and insert: a memories table with EmbeddingIndex, a @pxt.query that recalls nearest rows, and a conversations table whose computed columns retrieve then call the model. Pixeltable is not Mem0, Letta, or Zep. It does not ship Memory Decay, sleep-time agents, or a temporal fact graph. Keep Mem0, Letta, or Zep when that product is the memory layer; store transcripts, tool results, or media beside it in tables if you need them. Docs: Build an agent with memory.

import pixeltable as pxt
from pixeltable.functions.openai import embeddings, chat_completions
TableModel = pxt.model_base()
class Memories(TableModel, name='memories'):
content: pxt.String
category: pxt.String
__indexes__ = [
pxt.EmbeddingIndex(
content,
string_embed=embeddings.using(model='text-embedding-3-small'),
),
]
@pxt.query
def recall_memories(context: str, top_k: int = 3):
sim = Memories.content.similarity(string=context)
return (
Memories.where(sim > 0.5)
.order_by(sim, asc=False)
.limit(top_k)
.select(Memories.content, Memories.category)
)
@pxt.udf
def build_prompt(memories: list[dict], user_message: str) -> str:
memory_lines = '\n'.join(row['content'] for row in memories)
return f'Relevant memories:\n{memory_lines}\n\nUser: {user_message}'
class Conversations(TableModel, name='conversations'):
user_message: pxt.String
relevant_memories = recall_memories(user_message, top_k=3)
prompt = build_prompt(relevant_memories, user_message)
response = chat_completions(
messages=[{'role': 'user', 'content': prompt}],
model='gpt-4o-mini',
)
assistant_reply = response.choices[0].message.content

Questions

Which agent memory system should I use?

Mem0 for extracted memories with optional decay. Letta for agents that edit in-context blocks and search an archive. Zep for temporal facts with provenance. Pixeltable when memory is rows and indexes you own, not a dedicated memory SaaS.

Does Mem0 delete old memories when decay is on?

No. Official docs: decay is a search-time scaling factor between about 0.3x and 1.5x. It never filters a candidate out. Use expiration or delete to hide or remove a memory.

Can a Letta agent delete archival memory?

Official archival-memory docs: agents cannot easily modify or delete archival memories. Developers can via client.agents.passages.* including delete.

Does Zep forget on a timer by default?

No. Context stays until a caller deletes it, a retention policy fires, or (free-plan US accounts) the account is deleted after inactivity. See https://help.getzep.com/context-retention.md

Next step

Install the Pixeltable skill, or sign up for Cloud and run the same file on a hosted database.