ConversationBufferMemory was deprecated in LangChain v0.3.1 and is scheduled for removal at v1.0.0. The replacement is LangGraph persistence: a checkpointer for in-thread session history and a BaseStore for cross-thread, user-scoped long-term facts. On top of that foundation, you can layer the LangMem SDK for semantic and procedural memory, or connect ZepCloudMemory for temporal reasoning.
This guide covers all five approaches with verified import paths:
- Approach 1 (deprecated):
ConversationBufferMemory: what to remove and why - Approach 2: LangGraph checkpointer (
MemorySaver,SqliteSaver,PostgresSaver): in-session memory - Approach 3: LangGraph
BaseStore: cross-session, user-scoped long-term memory - Approach 4: LangMem SDK (
create_manage_memory_tool): semantic, episodic, and procedural memory - Approach 5:
ZepCloudMemory: temporal memory, with the fix for GitHub issue #27356
One production caveat up front: LangMem’s p95 search latency on the LOCOMO benchmark is 59.82 seconds. If your agent needs sub-second memory recall, use Mem0 (0.200s p95) or Zep instead.
Time to complete: 30-90 minutes per approach | Difficulty: Intermediate | Prerequisites: Python 3.10+, LangChain or LangGraph installed, LLM API key
For the architecture decision that precedes this implementation, see our guide on how to build a memory layer for AI agents.
Why LangChain’s original memory is no longer enough
Permalink to “Why LangChain’s original memory is no longer enough”ConversationBufferMemory and its relatives were built before the modern Chat Model API existed. They cannot work reliably with tool-calling agents, and they store state only in process memory. Restart the Python process and all conversation history is gone.
As of LangChain v0.3.1, these classes are deprecated, with removal scheduled at v1.0.0:
ConversationBufferMemoryConversationBufferWindowMemoryConversationSummaryMemoryConversationEntityMemory
The root cause of the deprecation was not just in-process storage. These classes were designed for a pre-tool-calling world. When agents started using tool calls, function schemas, and structured outputs, the old memory classes could not reliably intercept and store that flow. They also had no concept of multi-user or multi-thread operation. One ConversationBufferMemory object = one conversation = no persistence, no separation, no production viability.
LangGraph introduced two primitives that fix this cleanly:
- Checkpointer: manages conversation history within a single
thread_id. Conversation turns for the current session. Survives restarts if you useSqliteSaverorPostgresSaver. Does not survive athread_idchange. - BaseStore: manages facts that survive across ALL sessions for a user. Namespaced by user identity, not by thread. A returning user with a new
thread_idstill gets their stored preferences.
If you are hitting DeprecationWarning: ConversationBufferMemory is deprecated, you are at exactly the right place. See also: why AI agents forget: the stateless LLM problem for the deeper architectural reason this pattern fails.
Prerequisites
Permalink to “Prerequisites”Before writing any code, confirm these:
Organizational prerequisites:
- [ ] Decide on scope: in-session memory only (checkpointer), cross-session memory (store), or both
- [ ] Choose your backend: dev =
MemorySaver+InMemoryStore(resets on restart); local persistent dev =SqliteSaver; production =PostgresSaver+PostgresStore
Technical prerequisites:
- [ ]
langchain-core>=0.3,langgraph>=0.2,langgraph-prebuiltinstalled - [ ] For Zep:
langchain-community>=0.3andzep-python>=2.0(older versions cause GitHub issue #27356ImportErrorand issue #25791TypeError) - [ ] For LangMem:
langmeminstalled; an embedding model API key (e.g., OpenAItext-embedding-3-smallfor vector search inInMemoryStore) - [ ] For production postgres backends:
langgraph-checkpoint-postgres,langgraph-store-postgres, and a running Postgres instance
Time commitment:
- Setup + dev test: 30-60 minutes per approach
- Production backend swap: 1-3 hours
- Full multi-approach evaluation: 1 day
Step 1: Understand what you’re replacing, and why
Permalink to “Step 1: Understand what you’re replacing, and why”What you’ll accomplish: Map the deprecated ConversationBufferMemory pattern to its LangGraph equivalent so you know exactly what to change.
Time required: 10 minutes (review your existing code)
Here is the pattern you are replacing:
# DEPRECATED as of LangChain v0.3.1 — do not use in new code
# Scheduled for removal at v1.0.0
from langchain.memory import ConversationBufferMemory # raises DeprecationWarning
from langchain.chains import ConversationChain
memory = ConversationBufferMemory()
chain = ConversationChain(llm=llm, memory=memory)
Why this breaks: State lives in process RAM. Agent restart = total memory loss. No multi-user support, no multi-thread support. Breaks when tool-calling is in the loop because these classes predate the modern Chat Model API.
The most common architecture mistake
Permalink to “The most common architecture mistake”Most developers migrating to LangGraph make this mistake: they use the checkpointer as a drop-in for ConversationBufferMemory and expect it to remember user preferences across sessions. It does not. The checkpointer is in-thread. A returning user with a new thread_id gets a blank slate, because their preferences were stored in the checkpointer (scoped to the old thread_id) instead of the store (scoped to their user ID).
Developers only discover this in production, when a real returning user reports that the agent has forgotten everything about them.
The conceptual split:
thread_idscopes one conversation session (checkpointer)user_idscopes all sessions for one person (store namespace)- One user has many
thread_ids. The store is keyed by user, not by thread.
How to audit your codebase:
- Search for
from langchain.memory importand list every import - Classify each: does it store conversation turns (replace with checkpointer) or user/entity facts (replace with store)?
- Remove all
ConversationChainwired to a legacy memory object
Validation checklist:
- [ ] All
from langchain.memory import ...lines identified - [ ] Each one classified: conversation history use → checkpointer; persistent facts use → store
- [ ] No remaining
ConversationChainwired to a legacy memory object
Step 2: Add in-thread memory with a LangGraph checkpointer
Permalink to “Step 2: Add in-thread memory with a LangGraph checkpointer”What you’ll accomplish: Wire a checkpointer to a create_react_agent call so your agent remembers everything within a single conversation session, across restarts, as long as you pass the same thread_id.
Time required: 15-20 minutes
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver # dev / testing only; resets on restart
# For local persistent dev (survives restarts):
from langgraph.checkpoint.sqlite import SqliteSaver
# For production (multi-server, shared state):
# from langgraph.checkpoint.postgres import PostgresSaver
# Dev:
checkpointer = MemorySaver()
# Local persistent dev (recommended over MemorySaver for any real testing):
# checkpointer = SqliteSaver.from_conn_string("checkpoints.sqlite")
agent = create_react_agent(model=llm, tools=tools, checkpointer=checkpointer)
# Every invoke call for the SAME conversation must pass the SAME thread_id.
# Start a new thread_id when a new session begins.
config = {"configurable": {"thread_id": "user-123-session-1"}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "My name is Alex and I prefer Python examples."}]},
config=config
)
# Later turn in the same session — agent recalls "Alex prefers Python examples":
result2 = agent.invoke(
{"messages": [{"role": "user", "content": "What do you remember about my preferences?"}]},
config=config # same thread_id = same conversation history
)
The checkpointer stores the full message history for this thread_id. Change the thread_id and the agent starts fresh. Restart the Python process with SqliteSaver and the agent still has the history. Restart with MemorySaver and it is gone.
Key limitation: Memory is scoped to thread_id only. A new session (new thread_id) = blank slate. Use this for within-session context. Use Step 3 for facts that should survive across sessions.
One undocumented pitfall: In some LangGraph versions, langgraph dev ignores checkpointer configuration and defaults to in-memory storage. Agents appear to persist state, but they do not. Always verify persistence with direct Python invocation, not just langgraph dev.
Validation checklist:
- [ ] Agent compiled with
checkpointer=parameter - [ ]
thread_idpassed consistently inconfig - [ ]
SqliteSaverfile written to disk (visible after first run) - [ ] After process restart, same
thread_idrecovers full history
Common mistakes:
- Using
MemorySaverin production (resets on restart; state is gone) - Assuming
langgraph devis testing real persistence; always test with direct Python invocation
Still deciding between in-context and external memory? See our architectural comparison of in-context vs external memory for AI agents before committing to a backend.
Build Your AI Context Stack
Move from isolated memory to a complete, governed context layer for your AI agents.
Get the Stack GuideStep 3: Add cross-thread long-term memory with LangGraph BaseStore
Permalink to “Step 3: Add cross-thread long-term memory with LangGraph BaseStore”What you’ll accomplish: Wire a BaseStore alongside the checkpointer so your agent can write and retrieve facts that survive across ALL sessions for a given user.
Time required: 20-30 minutes
This is the step most tutorials skip. The checkpointer remembers conversations. The store remembers users. A new thread_id for a returning user should never mean a blank slate; it only does if you stored user preferences in the checkpointer instead of the store.
from langgraph.store.memory import InMemoryStore # dev / testing only; resets on restart
# For production:
# from langgraph.store.postgres import PostgresStore
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver
store = InMemoryStore()
# CRITICAL: compile with BOTH checkpointer AND store.
# Passing only one is the single most common LangGraph memory architecture mistake.
agent = create_react_agent(
model=llm,
tools=tools,
checkpointer=MemorySaver(), # in-thread context (current conversation history)
store=store # cross-thread facts (user preferences, learned facts)
)
# Writing to store from a node:
# CRITICAL DISTINCTION:
# thread_id -> scopes ONE conversation session (checkpointer, changes per session)
# user_id -> scopes ALL sessions for one person (store namespace root, NEVER changes)
#
# One user has many thread_ids.
# Store is keyed by user_id, not by thread_id.
namespace = ("user-123", "preferences") # namespace = (user_id, category)
store.put(namespace, "timezone", {"value": "America/New_York"})
store.put(namespace, "language", {"value": "Python"})
# Reading from store in a node (survives thread changes):
memories = store.search(namespace, query="timezone preference")
# OR exact lookup:
timezone = store.get(namespace, "timezone")
# When the same user starts a NEW session (new thread_id), their stored facts are still here:
config_new_session = {"configurable": {"thread_id": "user-123-session-2"}}
# The checkpointer context is fresh, but store.get(("user-123", "preferences"), "timezone")
# still returns "America/New_York"
For production, replace InMemoryStore() with PostgresStore. The API is identical; only the import and constructor change:
# Production store (swap one line):
from langgraph.store.postgres import PostgresStore
store = PostgresStore.from_conn_string("postgresql://user:pass@host/dbname")
For the decision framework on which memory architecture fits your use case, see how to choose an AI agent memory architecture.
Validation checklist:
- [ ]
create_react_agentcalled with bothcheckpointer=andstore= - [ ] Namespace tuple uses
user_id(notthread_id) as root key - [ ] Store retains value when agent is re-invoked with a different
thread_idfor the same user
Common mistakes:
- Passing only
checkpointerwhen you need cross-session memory (the single most common architecture mistake) - Using
thread_idas the namespace root in the store (creates per-session silos instead of per-user memory)
Step 4: Add semantic memory with the LangMem SDK
Permalink to “Step 4: Add semantic memory with the LangMem SDK”What you’ll accomplish: Layer the LangMem SDK on top of LangGraph’s BaseStore to give your agent three memory types: semantic (user facts and preferences), episodic (past interaction examples), and procedural (self-updated system prompts).
Time required: 20-30 minutes
LangMem is the only option in this stack where the agent can rewrite its own system prompt based on accumulated experience (procedural memory). No equivalent exists in Mem0 or Zep. If your agent needs to adapt its behavior from what it has learned, not just recall stored facts, LangMem adds that capability.
from langmem import create_manage_memory_tool, create_search_memory_tool
from langgraph.store.memory import InMemoryStore
from langgraph.prebuilt import create_react_agent
from langchain.chat_models import init_chat_model # requires langchain>=0.2
# The embedding index is REQUIRED for semantic search.
# Without it, store.search() returns nothing.
store = InMemoryStore(
index={
"dims": 1536,
"embed": "openai:text-embedding-3-small",
}
)
# Namespace all memories under the user's ID — NOT their thread_id.
manage_memory = create_manage_memory_tool(namespace=("user-123",))
search_memory = create_search_memory_tool(namespace=("user-123",))
agent = create_react_agent(
model=init_chat_model("anthropic/claude-3-5-sonnet-20241022"),
tools=[manage_memory, search_memory],
store=store
)
# For production: replace InMemoryStore with PostgresStore (one line change)
# from langgraph.store.postgres import PostgresStore
# store = PostgresStore.from_conn_string("postgresql://user:pass@host/dbname")
The three memory types LangMem manages:
- Semantic: User preferences and factual knowledge (“user works in Pacific time, prefers Python examples”)
- Episodic: Past interactions distilled as few-shot examples (“last time the agent solved X by doing Y”)
- Procedural: Updated system instructions the agent writes to itself (“always confirm before deleting”): unique to LangMem
Production caveat: do not skip this.
LangMem’s p95 search latency on the LOCOMO benchmark is 59.82 seconds. That is not a typo. LangMem also scores 58.10% accuracy on LOCOMO, versus Mem0’s 67.13% with 0.200s p95 latency (arXiv 2504.19413).
- LangMem (59.82s p95): Use for background or batch memory tasks, or non-latency-sensitive applications. Do not deploy for interactive user-facing agents.
- Mem0 (0.200s p95, 67.13% LOCOMO): Best for interactive production agents requiring sub-second memory retrieval and high accuracy.
- Zep: Best when temporal reasoning over interaction sequences matters.
This distinction will not surface in development testing. It surfaces in production user complaints.
For a full comparison across memory frameworks, see best AI agent memory frameworks 2026.
Validation checklist:
- [ ]
InMemoryStoreconfigured withindexdict (dims + embed model) - [ ] Both manage and search tools passed to agent
- [ ] Agent successfully saves and retrieves a test memory across invocations
Common mistakes:
- Deploying LangMem for interactive agents without measuring actual latency (59.82s p95 will appear in production user complaints)
- Skipping the embedding index configuration;
store.search()returns nothing without it
Inside Atlan AI Labs & The 5x Accuracy Factor
See how context-grounded AI agents outperform memory-only agents on accuracy benchmarks.
Download E-BookStep 5: Use Zep for temporal memory (and fix the import error)
Permalink to “Step 5: Use Zep for temporal memory (and fix the import error)”What you’ll accomplish: Connect your LangChain agent to ZepCloud with the correct import path and all ZepCloudMemory interface fields documented, plus the fix for GitHub issue #27356.
Time required: 20-30 minutes (plus Zep account setup)
Zep’s differentiator is temporal reasoning. It structures interactions into meaningful sequences and knows not just what a user said, but when, and how that event relates to subsequent events. This makes it architecturally closer to an episodic memory store than flat vector search.
The import error that sends developers to GitHub
Permalink to “The import error that sends developers to GitHub”The old import paths are broken in current langchain-community versions. Here is the exact error and the exact fix:
# DO NOT USE — raises ImportError: cannot import name 'ZepClient' from 'zep_python'
from langchain.memory.zep_memory import ZepMemory
from langchain_community.memory.zep_memory import ZepMemory # also broken in recent versions
Error message you will see:
ImportError: cannot import name 'ZepClient' from 'zep_python'
Root cause: The zep_python package v2.0 removed the ZepClient class. The old zep_memory module still imports it, causing the error on any system with zep-python>=2.0.
Fix: Upgrade packages and use the correct module:
pip install "langchain-community>=0.3" "zep-python>=2.0"
# CORRECT import path (requires langchain-community>=0.3 + zep-python>=2.0):
from langchain_community.memory.zep_cloud_memory import ZepCloudMemory
# OR for chat message history:
from langchain_community.chat_message_histories import ZepCloudChatMessageHistory
ZepMemoryInput interface: all fields
Permalink to “ZepMemoryInput interface: all fields”This is the interface developers search for while staring at a blank ZepCloudMemory() constructor:
memory = ZepCloudMemory(
session_id="user-123", # Required. Stable per-user identifier.
# DO NOT set this to a per-request UUID —
# temporal continuity requires a stable, reused ID.
api_key="your-zep-api-key", # Required for ZepCloud.
url="http://localhost:8000", # Required ONLY for self-hosted Zep OSS.
# Omit when using ZepCloud.
memory_key="chat_history", # Key name for history injected into chain.
# Must exactly match the variable name in your prompt template.
input_key=None, # Key for input variable in chain. None = auto-detect.
output_key=None, # Key for output variable in chain. None = auto-detect.
return_messages=False, # True = returns a list of BaseMessage objects.
# False = returns a formatted string.
# Use True for chat models; False for completion models.
human_prefix="Human", # Label for human turns when return_messages=False.
ai_prefix="AI", # Label for AI turns when return_messages=False.
)
Secondary error (GitHub issue #25791): If you see TypeError: ZepCloudMemory() takes no arguments, the cause is a version mismatch between langchain-community and zep-python. Upgrading both packages to the versions above resolves it.
Validation checklist:
- [ ]
langchain-community>=0.3andzep-python>=2.0installed - [ ] Import from
zep_cloud_memory(notzep_memory) resolves without error - [ ]
session_idset to a stable per-user identifier (not a per-request UUID) - [ ]
memory_keyinZepCloudMemorymatches the variable name in your prompt template
Common mistakes:
- Using
from langchain_community.memory.zep_memory import ZepMemory: this is the wrong module;zep_cloud_memoryis correct - Setting
session_idto a per-request UUID (destroys temporal memory; Zep needs the same ID across sessions) - Version mismatch: if
ZepCloudMemory() takes no argumentsappears, upgrade both packages
Common implementation pitfalls
Permalink to “Common implementation pitfalls”These are the five mistakes that send developers back to Stack Overflow after they think they have finished implementing memory.
Pitfall 1: Storing user preferences in the checkpointer
Permalink to “Pitfall 1: Storing user preferences in the checkpointer”Why it happens: The checkpointer works in testing where thread_id never changes. In production, returning users get new thread_ids, and all “remembered” preferences vanish.
How to avoid it: Facts about a user go in the store, namespaced by user ID. Conversation turns go in the checkpointer, scoped by thread ID.
If you encounter it: Migrate preference data from checkpointer snapshots to the store; update agent code to write to the store from day one.
Pitfall 2: Using MemorySaver in production
Permalink to “Pitfall 2: Using MemorySaver in production”Why it happens: Works perfectly in development. Easy to miss the “dev / testing only” annotation.
How to avoid it: Use SqliteSaver for local persistent development. Use PostgresSaver for production from the start.
Pitfall 3: The langgraph dev checkpointer blind spot
Permalink to “Pitfall 3: The langgraph dev checkpointer blind spot” Why it happens: In some LangGraph versions, langgraph dev ignores checkpointer configuration and defaults to in-memory storage. Agents appear to persist state, but they do not.
How to avoid it: Always verify persistence with direct Python invocation, not via langgraph dev.
Pitfall 4: Deploying LangMem for interactive agents
Permalink to “Pitfall 4: Deploying LangMem for interactive agents”Why it happens: LangMem is the “official” LangGraph memory SDK, so teams assume it is production-ready for all use cases.
How to avoid it: LangMem’s 59.82s p95 latency makes it impractical for real-time interaction. If you need sub-second memory retrieval, use Mem0 (0.200s p95) or Zep instead.
Pitfall 5: Broken Zep import path
Permalink to “Pitfall 5: Broken Zep import path”Why it happens: The old zep_memory module existed in older versions and is still referenced in cached search results. Developers import it, hit the ZepClient error, and spend an hour debugging.
How to avoid it: Always import from langchain_community.memory.zep_cloud_memory. Verify langchain-community>=0.3 and zep-python>=2.0 are installed.
Best practices for LangChain long-term memory
Permalink to “Best practices for LangChain long-term memory”Commit these five practices before you deploy:
Practice 1: Always compile with both checkpointer AND store.
Passing only one is the most common architecture mistake. checkpointer handles session continuity; store handles cross-session facts. You need both for a complete memory layer.
Practice 2: Namespace the store by user identity, not by thread.
Namespace tuple root = user_id. Every store operation for a given user hits the same namespace regardless of how many sessions they have had.
Practice 3: Match the memory tool to your latency requirement.
- LangMem (59.82s p95) → background or batch agents only
- Mem0 (0.200s p95, 67.13% LOCOMO accuracy) → interactive production agents
- Zep → agents requiring temporal reasoning over interaction history
Practice 4: Use stable session IDs for Zep.
A session_id that changes per request destroys temporal continuity. Use a stable per-user identifier that persists across the user’s lifetime in your system.
Practice 5: Swap InMemoryStore for PostgresStore before production.
InMemoryStore resets on restart. The API is identical; one import line changes. Write the swap into your deployment checklist before the first staging push.
When memory isn’t enough: enterprise data agents and Atlan’s context layer
Permalink to “When memory isn’t enough: enterprise data agents and Atlan’s context layer”Memory systems (LangMem, Zep, Mem0, checkpointers) solve session continuity and user-fact retrieval across sessions. They do not answer “is this table certified?”, “who owns this column?”, or “has this metric definition changed?” Those are context layer questions, and the distinction is architectural.
After implementing LangMem or Zep, enterprise data agents still return wrong answers in these scenarios:
- Querying Snowflake tables whose definitions have changed since the agent last saw them
- Hitting deprecated columns that exist in lineage but not in any memory store
- Resolving
net_revenueconflicts across Looker and dbt, where the agent’s stored definition was correct last week but finance updated the glossary term yesterday
No memory system can tell an agent whether a table is certified, who owns a column, or whether a stored metric definition is still canonical. That requires live, governed metadata, not stored recollection.
This is where Atlan’s context layer fits. Atlan’s MCP server is callable from any LangChain agent via langchain-mcp-adapters. Where LangMem remembers what a user said in a past session, Atlan tells the agent what is true about the data right now: certifications, ownership, sensitivity labels, lineage, and governance policies, propagated automatically across Snowflake, Looker, Slack, and every connected system. Agents can query Atlan by DSL, traverse lineage, check data quality, and update asset metadata without a human trigger.
Workday is already using Atlan this way: “All of the work that we did to get to a shared language at Workday can be leveraged by AI via Atlan’s MCP server…as part of Atlan’s AI Labs, we’re co-building the semantic layer that AI needs with new constructs, like context products.”
For enterprise data agents specifically, the architectural question is not which memory tool to choose; it is whether memory alone is sufficient. The line between memory layer and context layer determines that answer.
See how Atlan’s context layer works alongside LangGraph agents: Atlan Context Layer: Enterprise AI Agent Memory.
AI Context Maturity Assessment
Find out whether your AI agents need a memory layer, a context layer, or both.
Check Context MaturityReal stories: enterprise context layers in production
Permalink to “Real stories: enterprise context layers in production”"AI initiatives require more context than ever. Atlan's metadata lakehouse is configurable, intuitive, and able to scale to hundreds of millions of assets."
— Andrew Reiskind, Chief Data Officer, Mastercard
"Context is the differentiator. Atlan gave our teams the shared vocabulary and lineage to move from reactive data management to proactive AI enablement across CME Group."
— Kiran Panja, Managing Director, Data & Analytics, CME Group
Memory or context? What the right architecture actually looks like
Permalink to “Memory or context? What the right architecture actually looks like”The five approaches in this guide give you a complete map of LangChain’s memory landscape. The deprecated path tells you what to remove. The checkpointer gives you session continuity. The BaseStore gives you cross-session user memory. LangMem adds semantic and procedural memory. Zep adds temporal reasoning.
Each one solves a real problem. The decision criteria are clear: use LangMem only for batch workloads (59.82s p95 is real), use the store for user facts and the checkpointer for conversation turns (never conflate the two), and fix the Zep import path before debugging anything else.
The boundary to watch is the one between memory and context. For teams building agents that query governed data systems (Snowflake, Looker, dbt), memory alone does not answer “what is true about this data right now?” That is the architectural question that takes you from a working memory implementation to a production-grade enterprise agent.
Next steps after implementation:
Once your checkpointer and store are running, measure actual memory retrieval latency in your target deployment environment. Development numbers are not representative; InMemoryStore has no network round-trip cost that PostgresStore does.
For production backend selection: PostgresStore + PostgresSaver is the standard path. If your team is already running Redis, it is a viable alternative; see the Redis + LangGraph integration pattern for setup details.
For the compliance and access-control considerations that follow a memory implementation, see AI agent memory governance. For the architecture path beyond a single-agent deployment, see enterprise AI memory layer: architecture for data leaders.
Ready to add a governed context layer to your LangChain agents?
Book a DemoFAQs about long-term memory in LangChain agents
Permalink to “FAQs about long-term memory in LangChain agents”1. How do I add persistent memory to a LangChain agent across sessions?
Permalink to “1. How do I add persistent memory to a LangChain agent across sessions?”Use LangGraph’s BaseStore alongside a checkpointer. The checkpointer (SqliteSaver for local dev, PostgresSaver for production) maintains conversation history within a session. The BaseStore (PostgresStore for production) stores facts that survive across sessions, namespaced by user ID. Both are passed to create_react_agent at compile time. Without the store, memory resets every time a user starts a new conversation.
2. What replaced ConversationBufferMemory in LangChain?
Permalink to “2. What replaced ConversationBufferMemory in LangChain?”LangGraph persistence replaced it. ConversationBufferMemory was deprecated in LangChain v0.3.1 and is scheduled for removal at v1.0.0. The replacement is a LangGraph checkpointer (MemorySaver for dev, SqliteSaver or PostgresSaver for production) passed to create_react_agent. Also deprecated: ConversationBufferWindowMemory, ConversationSummaryMemory, and ConversationEntityMemory. All follow the same migration path.
3. What is the difference between a LangGraph checkpointer and a store?
Permalink to “3. What is the difference between a LangGraph checkpointer and a store?”A checkpointer manages conversation history within a single session, scoped by thread_id. A store manages facts that persist across all sessions, scoped by user or entity namespace. A new thread_id (new session) clears checkpointer context but never touches the store. For an agent that should remember a user’s preferences across multiple conversations, you need both; passing only a checkpointer is the most common architecture mistake.
4. How do I fix the ZepMemory ImportError in LangChain (issue #27356)?
Permalink to “4. How do I fix the ZepMemory ImportError in LangChain (issue #27356)?”Upgrade to langchain-community>=0.3 and zep-python>=2.0, then change your import to from langchain_community.memory.zep_cloud_memory import ZepCloudMemory. The old paths (from langchain.memory.zep_memory import ZepMemory and from langchain_community.memory.zep_memory import ZepMemory) raise ImportError: cannot import name 'ZepClient' from 'zep_python' in current versions. A secondary error (ZepCloudMemory() takes no arguments, issue #25791) also resolves with the package version upgrade.
5. What are all the fields in the ZepMemoryInput interface?
Permalink to “5. What are all the fields in the ZepMemoryInput interface?”ZepCloudMemory accepts: session_id (required, stable per-user identifier), api_key (required for ZepCloud), url (required only for self-hosted Zep OSS), memory_key (key name for history injected into the chain, must match your prompt template), input_key (auto-detect if None), output_key (auto-detect if None), return_messages (True for BaseMessage list, False for formatted string), human_prefix, and ai_prefix.
6. Is LangMem fast enough for production use?
Permalink to “6. Is LangMem fast enough for production use?”Not for interactive agents. LangMem’s p95 search latency is 59.82 seconds on the LOCOMO benchmark, versus Mem0’s 0.200 seconds. LangMem also scores 58.10% accuracy versus Mem0’s 67.13%. For background or batch memory tasks where latency is not critical, LangMem works well. For interactive production agents requiring sub-second memory retrieval, use Mem0 or Zep instead.
7. What is the difference between MemorySaver and SqliteSaver?
Permalink to “7. What is the difference between MemorySaver and SqliteSaver?”MemorySaver stores checkpointer state in process RAM: fast, zero setup, but resets when the Python process ends. Use it only for development and testing. SqliteSaver writes checkpoints to a local SQLite file that persists across restarts. Use it for local development that needs real persistence. For production multi-server deployments, use PostgresSaver to share state across instances.
8. Should I use LangMem, Mem0, or Zep for my LangChain agent?
Permalink to “8. Should I use LangMem, Mem0, or Zep for my LangChain agent?”It depends on your use case. LangMem integrates natively with LangGraph and uniquely supports procedural memory (agents rewriting their own system prompts) but has 59.82s p95 latency, which makes it unsuitable for real-time interaction. Mem0 is fastest (0.200s p95) with the highest LOCOMO accuracy (67.13%), making it best for interactive personalization. Zep adds temporal reasoning over interaction sequences, making it best when the ordering of what a user said, and when, matters to the agent’s reasoning.
Sources
Permalink to “Sources”- Migrating off ConversationBufferMemory, python.langchain.com, Official deprecation guide and migration table
- Launching Long-Term Memory Support in LangGraph, LangChain blog, BaseStore and checkpointer pattern announcement
- LangMem SDK for agent long-term memory, LangChain blog, Canonical SDK launch post with memory type definitions
- AI Memory Wars: Mem0 vs OpenAI vs LangMem benchmark, guptadeepak.com, LangMem 59.82s p95 latency data on LOCOMO benchmark
- Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory, arXiv 2504.19413, Mem0 benchmark data: 0.200s p95, 67.13% LOCOMO accuracy, 91% token reduction
- LangChain Zep Integration Fails Due to Deprecated Import, GitHub issue #27356, Root cause and confirmed fix for ZepClient ImportError
- Adding Long-Term Memory to LangGraph and LangChain Agents, Hindsight/Vectorize, March 2026 production implementation tutorial
- Mem0 vs Zep vs LangMem: AI Agent Memory Comparison 2026, DEV Community, Community use-case comparison
- LangGraph & Redis: Build smarter AI agents, Redis blog, Redis as a production store backend option
Share this article
