Skip to content
Membase
LangChain and LangGraph Memory: How to Add Long-Term Memory to Agents

LangChain and LangGraph Memory: How to Add Long-Term Memory to Agents

Checkpointers, Stores and LangMem, with Code, and How to Share Agent Memory Across Tools

Research
MembaseMembase Team
View the original post on Medium

Disclosure: Membase is our product. LangChain’s built-in memory is solid, and for many agents it’s all you need. We cover it first. Facts and code were checked against LangChain’s documentation in November 2026.

Quick answer

LangChain agents have two kinds of memory, both built on LangGraph:

Short-term memoryLong-term memory
ScopeOne thread (conversation)Across threads and sessions
What it holdsThe conversation history and other agent stateFacts, preferences and other data you choose to keep
How you add itPass a checkpointer to create_agentPass a store to create_agent
Keyed bythread_idA namespace and key, for example a user ID

Use LangMem on top of the store if you want the agent to extract and update memories for you.

The older memory classes, such as ConversationBufferMemory, are deprecated. Current LangChain uses checkpointers and stores instead.

In this guide: Short-term memory · Managing long conversations · Long-term memory · LangMem · Which to use · Where LangChain memory stops · Share memory with your other AI tools · FAQ

Short-term memory: checkpointers

Short-term memory lets an agent remember earlier messages in the same thread. LangChain keeps it as part of the agent’s state and saves it with a checkpointer, so you can resume the thread at any time.

from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    "gpt-5.5",
    tools=[],
    checkpointer=InMemorySaver(),
)

config = {"configurable": {"thread_id": "1"}}
agent.invoke({"messages": [{"role": "user", "content": "Hi! My name is Bob."}]}, config)
agent.invoke({"messages": [{"role": "user", "content": "What's my name?"}]}, config)
# "You are Bob!"

A new thread_id starts a fresh conversation.

In production, use a database-backed checkpointer. InMemorySaver loses everything when the process stops. For Postgres:

pip install -U langgraph-checkpoint-postgres "psycopg[binary]"
from langchain.agents import create_agent
from langgraph.checkpoint.postgres import PostgresSaver

DB_URI = "postgresql://user:password@localhost:5432/db"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
    checkpointer.setup()  # creates the tables
    agent = create_agent("gpt-5.5", tools=[], checkpointer=checkpointer)

Checkpointers are also available for SQLite and Azure Cosmos DB, among others.

Add your own fields. By default, short-term memory holds the messages. Extend AgentState to keep more, such as a user ID or preferences, and pass it as state_schema.

Managing long conversations

Long threads eventually overflow the model’s context window, and most models do worse with long, stale context anyway. LangChain gives you four options:

OptionWhat it doesHow
TrimKeep only recent messages before calling the modelA @before_model middleware
DeleteRemove messages from the state permanentlyRemoveMessage
SummarizeReplace older messages with a summaryThe built-in SummarizationMiddleware
CustomFilter messages your own wayYour own middleware

Summarizing keeps more information than trimming:

from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    "gpt-5.5",
    tools=[],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger=("tokens", 4000),
            keep=("messages", 20),
        )
    ],
    checkpointer=InMemorySaver(),
)

Long-term memory: stores

Long-term memory persists across threads. It’s built on LangGraph stores, which save JSON documents under a namespace (like a folder) and a key (like a file name). Namespaces usually include a user or organization ID.

1. Give the agent a store:

from langchain.agents import create_agent
from langgraph.store.memory import InMemoryStore

store = InMemoryStore()  # use a database-backed store in production
agent = create_agent("gpt-5.5", tools=[], store=store)

2. Let tools read and write it through runtime.store:

from dataclasses import dataclass
from typing_extensions import TypedDict
from langchain.agents import create_agent
from langchain.tools import ToolRuntime, tool
from langgraph.store.memory import InMemoryStore

store = InMemoryStore()

@dataclass
class Context:
    user_id: str

class UserInfo(TypedDict):
    name: str

@tool
def save_user_info(user_info: UserInfo, runtime: ToolRuntime[Context]) -> str:
    """Save user info."""
    runtime.store.put(("users",), runtime.context.user_id, dict(user_info))
    return "Saved."

@tool
def get_user_info(runtime: ToolRuntime[Context]) -> str:
    """Look up user info."""
    item = runtime.store.get(("users",), runtime.context.user_id)
    return str(item.value) if item else "Unknown user"

agent = create_agent(
    "gpt-5.5",
    tools=[save_user_info, get_user_info],
    store=store,
    context_schema=Context,
)

agent.invoke(
    {"messages": [{"role": "user", "content": "My name is John Smith"}]},
    context=Context(user_id="user_123"),
)

Search by meaning. Give the store an embedding function, and store.search can find memories by meaning as well as filter by content. Production stores include Postgres, Redis and MongoDB.

What to store. LangChain borrows three memory types from psychology:

TypeWhat’s storedAgent example
SemanticFactsFacts about a user
EpisodicExperiencesPast agent actions, often used as few-shot examples
ProceduralInstructionsThe agent’s own system prompt, refined over time

When to write. Either “in the hot path”, where the agent decides to save during the conversation (memories are available immediately, but it adds latency), or “in the background”, as a separate task after the conversation (no latency, but other threads see new memories later).

LangMem

LangMem is LangChain’s library for agent memory on top of the store. It gives you:

  • Memory tools the agent can call during a conversation to record and search information
  • A background memory manager that extracts, consolidates and updates memories automatically
  • Prompt refinement, so an agent can improve its own instructions from feedback
  • Native integration with LangGraph’s long-term memory store
pip install -U langmem

Use LangMem when you’d rather not write the save and search logic yourself.

Which should you use?

You wantUse
The agent to remember the current conversationA checkpointer
To resume a conversation after a restartA database-backed checkpointer
Long threads that don’t overflow the contextSummarizationMiddleware or trimming
Facts about each user across conversationsA store, namespaced by user ID
The agent to extract and update memories for youLangMem
The same memory in your agent and your AI toolsA shared memory layer, such as Membase

Where LangChain memory stops

LangChain’s memory lives in your application’s database. That’s right for an app, and it has limits:

  1. Your AI tools can’t see it. Claude Code, Cursor, Codex and ChatGPT don’t read your LangGraph store. A decision your agent learned stays inside your app.
  2. You build the memory logic. What to save, how to update changing facts, how to search: that’s your code, or LangMem’s.
  3. Several agents, separate access. Sharing one store across agents is possible, but giving each its own limited, revocable access is up to you.
  4. You run the storage. A production store and checkpointer are databases you set up and maintain.

Share your agent’s memory with your other AI tools

Membase is a hosted memory layer that both your LangChain agent and your AI tools can read. Your agent reads and writes through the SDK; Claude Code, Cursor, Codex and ChatGPT connect to the same memory over MCP.

1. Install the SDK and get a key at app.membase.com under Connect > Developer keys:

pip install unibaseio-membase
export MEMBASE_API_KEY=mbk_your_key

2. Give your agent Membase tools:

from langchain.agents import create_agent
from langchain.tools import tool
from membase import Membase

client = Membase()  # reads MEMBASE_API_KEY

@tool
def remember(note: str) -> str:
    """Save a fact or decision to long-term memory."""
    client.add(note)
    return "Saved."

@tool
def recall(query: str) -> str:
    """Search long-term memory for past facts and decisions."""
    return str(client.search(query, limit=5))

agent = create_agent("gpt-5.5", tools=[remember, recall])

Keep your checkpointer for the current conversation. Membase holds what should outlast it.

3. Connect your AI tools to the same memory. One command adds it to Claude Code, Cursor, Codex and other MCP clients:

npx add-mcp 'https://api.app.membase.com/mcp-http'

Now a decision your agent saved is there when you ask Claude Code about the same project, and every search result shows where it came from.

When to stay with a LangGraph store: if your app serves many end users behind one key and needs memory per user, a store namespaced by user ID fits better. Membase isolates memory per account, so each person would connect their own.

Frequently Asked Questions

How does memory work in LangChain?
Short-term memory keeps the current conversation, saved with a checkpointer per thread_id. Long-term memory keeps data across conversations in a LangGraph store, organized by namespace and key.
What is a LangGraph checkpointer?
It saves an agent’s state, including the conversation history, after each step, so a thread can be resumed later. Use InMemorySaver for testing and a database-backed one such as PostgresSaver in production.
What is a LangGraph store?
A place for long-term memories, saved as JSON documents under a namespace and key. Tools read and write it through runtime.store.
Is ConversationBufferMemory deprecated?
Yes. LangChain’s older memory classes are deprecated. Use a checkpointer for conversation history and a store for long-term memory.
What is LangMem?
LangChain’s library for agent memory. It adds memory tools, a background memory manager and prompt refinement on top of LangGraph’s store.
How do I stop long conversations overflowing the context window?
Trim old messages, delete them, or summarize them with SummarizationMiddleware.
What’s the difference between short-term and long-term memory in LangGraph?
Short-term memory is scoped to one thread. Long-term memory is shared across threads and sessions.
Can Claude Code or Cursor read my LangChain agent’s memory?
Not from a LangGraph store. With a shared memory layer such as Membase, your agent and your AI tools read the same memory.
Back to all posts