Every AI agent conversation starts from scratch. Your agent doesn’t remember that the user prefers concise answers, that their company uses AWS not Azure, or that last week they asked you to avoid suggesting Python solutions because their team is all TypeScript. Every session, you’re back to zero. For a demo, that’s fine. For a production assistant that people use daily, it’s a serious problem.
Mem0 is the most widely adopted answer to this. It’s a memory layer that sits between your agent and a vector store, handling the messy work of storing, retrieving, and updating what the agent learns across sessions. With around 48,000 GitHub stars and a $24M Series A closed in October 2025, it’s moved well past early-adopter territory.
The Architecture
Mem0 organises memory into three layers, which is the right call for most agent deployments.
User-level memories persist across all sessions for a given user. This is where you store preferences, profile information, and anything that stays true over time — “prefers bullet points”, “works in fintech”, “is based in London”. These survive indefinitely and are retrieved whenever that user starts a new conversation.
Session-level memories exist within a single conversation thread. They capture what’s been established in the current interaction and don’t bleed into future sessions unless you explicitly promote them. This is where intermediate facts live — things established this conversation that are relevant right now but might not be permanently important.
Agent-level memories capture what the agent itself learns during task execution. If your agent discovers that a particular API endpoint is rate-limited, or that a certain document structure means something specific, that can be stored as agent memory and reused.
This separation prevents memory bloat. Without it, you end up with a vector store stuffed with everything the agent has ever encountered, which means retrieval gets noisier as the dataset grows.
How Retrieval Works
The retrieval mechanism in Mem0’s April 2026 algorithm update is worth understanding. It uses a fused scoring approach combining semantic similarity search, BM25 keyword matching, and entity matching into a single score. That’s more robust than pure vector search because it catches both semantic matches (“the user likes detailed explanations”) and entity matches (“AWS”, “TypeScript”, specific names and terms).
The storage side uses an ADD-only pattern rather than the previous UPDATE/DELETE cycle. When new information arrives, Mem0 adds it as a new memory rather than trying to identify and update an existing one. This single-pass approach is what drives the performance improvements: 91% lower latency and 90% fewer tokens consumed compared to the previous version. In Mem0’s own benchmarks, it hits 91.6 on LoCoMo, 94.8 on LongMemEval, and 64.1 on BEAM at 1 million tokens — all substantial improvements over the previous version.
In practice, this means memory writes are fast and cheap, which matters if you’re calling them frequently during agentic workflows.
Getting Started
Installation:
pip install mem0ai
Basic usage with the managed API:
from mem0 import MemoryClient
client = MemoryClient(api_key="your-mem0-api-key")
# Store a memory for a user
client.add(
[{"role": "user", "content": "I prefer TypeScript over Python for all new projects."}],
user_id="user-123"
)
# Retrieve relevant memories before responding
memories = client.search("programming language preference", user_id="user-123")
for m in memories:
print(m["memory"])
The typical pattern in an agent workflow is to retrieve relevant memories at the start of a conversation, include them in the system prompt, and then store new memories at the end of the session or whenever the agent learns something worth keeping.
LangGraph Integration
For teams already using LangGraph, Mem0 fits into the state management pattern:
from mem0 import MemoryClient
from langchain_core.messages import SystemMessage
memory = MemoryClient(api_key="your-mem0-api-key")
def retrieve_memories(state):
user_id = state["user_id"]
query = state["messages"][-1].content
memories = memory.search(query, user_id=user_id, limit=5)
memory_text = "\n".join([m["memory"] for m in memories])
return {"memories": memory_text}
def agent_node(state):
memories = state.get("memories", "")
system = SystemMessage(content=f"User context:\n{memories}")
# Pass to your LLM...
Mem0 also maintains official integrations for CrewAI, AutoGPT, and the Vercel AI SDK, with community integrations for most other popular frameworks.
Self-Hosted vs Managed
The managed API is the fastest way to start — no infrastructure to run, just an API key and a monthly bill. For teams with data residency requirements or who want to avoid sending user data to a third party, Mem0’s open-source version can run against a self-hosted vector database (Qdrant, Weaviate, Chroma, or pgvector all work). There’s also an MCP server if you want to wire Mem0 into Claude Desktop or Claude Code directly.
The tradeoff on self-hosted is operational overhead. The managed version handles vector store scaling, embedding model updates, and the retrieval infrastructure. If you’re not running significant scale, the managed API is almost always the right starting point — you can migrate to self-hosted if your requirements later demand it.
What It Doesn’t Solve
Mem0 handles the storage and retrieval problem. It doesn’t solve the agent design problem — you still need to decide when to write memories, what context to include in retrieval queries, and how much memory to inject into prompts before you risk hitting context limits.
For long-running agents with very large memory stores, retrieval quality can degrade if the memories themselves are vague or overlapping. The quality of what goes in determines the quality of what comes out, which means thinking carefully about what’s worth storing and what’s noise.
Fair enough — no memory library solves that for you. But Mem0 does mean you can focus on those design decisions rather than building and maintaining the retrieval infrastructure from scratch.