What does memory mean in a current LangChain agent?
LangChain separates short-term agent memory from long-term memory. A short-term checkpointer persists agent state for a thread, so the same conversation can resume. A long-term Store keeps JSON documents by namespace and key across threads and sessions. The current LangChain agent documentation builds both capabilities on LangGraph persistence primitives.
That creates a useful boundary. The thread checkpoint keeps execution continuity. The Store keeps application data. Neither automatically decides which messages become durable facts, how conflicting facts are merged, or when a tenant deletion must remove every derived copy.
What is the difference between a LangChain checkpointer and a Store?
A checkpointer resumes one thread. A Store retrieves namespaced data beyond that thread. Both are persistence mechanisms, but they answer different questions: where did this run stop, and what should the agent know about this user or project next time?
| Layer | Primary question | Typical lifetime |
|---|---|---|
| Checkpointer | Can this thread resume with its messages and graph state? | The conversation or workflow thread |
| Store | What application-level JSON data exists for this namespace and key? | Policy-driven across threads |
| External memory API | Which durable facts, relations, versions and sources should be retrieved? | Policy-driven across frameworks and products |
| Source-of-truth database | What plan, permissions or account state is true now? | Authoritative until the business record changes |
How do you add a checkpointer and Store to a LangChain agent?
Pass the persistence objects when creating the agent. In-memory implementations are useful for examples and tests; use database-backed implementations in production. Keep the model and tools ordinary so the memory boundary remains visible rather than hidden inside a prompt.
- Use a database-backed checkpointer for durable thread state.
- Use a database-backed Store for production long-term application data.
- Namespace records by tenant, user, agent and project before adding a key.
- Keep account permissions and billing status in their authoritative systems.
import { createAgent } from 'langchain';
import { InMemoryStore, MemorySaver } from '@langchain/langgraph';
const checkpointer = new MemorySaver();
const store = new InMemoryStore();
const agent = createAgent({
model: process.env.AI_MODEL!,
tools,
checkpointer,
store,
});
const thread = {
configurable: { thread_id: 'support-thread-4821' },
};
await agent.invoke(
{ messages: [{ role: 'user', content: 'What do you remember?' }] },
thread
);When do you need an external memory layer with LangChain?
A native Store is enough when your team wants to own storage, extraction and retrieval, and when the application already has a complete lifecycle for identities, merging and deletion. Add a model-neutral memory layer when several frameworks or products need the same durable user context.
| Requirement | LangChain Store is sufficient when… | External memory is better when… |
|---|---|---|
| Runtime | One LangChain or LangGraph system owns the data | Other agents and services need the same memory |
| Quality | The application already implements extraction and reranking | Managed extraction, merge and token-budgeted retrieval are required |
| Identity | Namespaces map cleanly to existing product IDs | One contract must cover user, agent, project and tenant scopes |
| Portability | A custom export is acceptable | A framework-neutral export must survive runtime changes |
How should LangChain memory namespaces map to users and tenants?
Use the narrowest safe namespace and make tenant the outermost boundary. A useful order is tenant, user, agent and project. The Store key can identify the fact or document, but it must not become an alternate authorization path.
| Namespace segment | Example | Rule |
|---|---|---|
| Tenant | tenant:northwind | Required on every production read and write |
| User | user:dana | Required for personal memory |
| Agent | agent:support | Separates role-specific context |
| Project | project:migration | Limits shared facts to one initiative |
| Key | preferred-contact-window | Never includes secrets or sensitive raw text |
What happens when a LangChain thread grows beyond the context window?
Persisting a thread does not guarantee that the entire history can be sent to the model forever. Summarization, message removal and other compaction middleware reduce the active context while keeping the thread resumable. The compaction policy should preserve decisions, constraints, unresolved work and source references.
Do not confuse a compressed thread with durable user memory. A summary may be useful for one task and still contain details that should never follow the user into another product. Promote durable facts deliberately through the Store or external memory layer.
How should LangChain memory handle correction, deletion and export?
Define which system owns each record. Thread state may expire with the conversation; Store keys may follow a product retention rule; extracted memory may follow user and tenant policy. Deletion must call every layer that can answer a future query, including summaries, vector indexes and graph edges.
Test deletion by clearing the thread, deleting the relevant Store namespace and removing external memory, then query again. A user should not reappear because one layer retained an old summary or export.
How do you test LangChain memory before production?
Test four boundaries: resuming the same thread, recalling memory in a new thread, refusing a foreign tenant and deleting every copy. Keep retrieval quality separate from final answer quality so a model change cannot hide a memory regression.
| Scenario | Pass condition |
|---|---|
| Resume thread 4821 | The checkpointer restores the expected conversation state |
| Start a new thread for the same user | Only allowed durable memory follows the user |
| Use a similar user in another tenant | No cross-tenant Store key or memory is returned |
| Change a fact | The newest authorized fact wins while history stays auditable |
| Delete the user | Thread, Store, summaries and external memory disappear from future reads |
| Change frameworks | The exported durable memory can be replayed without losing source or scope |
What is the recommended LangChain memory architecture?
Use the checkpointer for execution state and the Store for application-owned records. Add an external memory contract when durable facts must span agents, services or runtimes. Resolve tenant identity outside the model, keep compaction separate from extraction and treat deletion as a cross-layer workflow.
Frequently asked questions
Does LangChain have built-in long-term memory?
Current LangChain agents can use a Store for data that persists across threads and sessions. The application still defines extraction, namespaces, correction, retention and deletion policy.
What is the difference between a checkpointer and a Store?
A checkpointer persists state for a thread so the agent can resume. A Store holds namespaced JSON documents that can be recalled across threads.
Do I still need an external memory API?
Add one when several runtimes share memory, when you need managed extraction and reranking, or when user and tenant lifecycle must be consistent beyond one LangChain application.
Are old LangChain memory classes still the recommended pattern?
Current agent documentation centers on checkpointer-based thread state and Store-based long-term memory. Check the current version rather than copying older memory-class examples.
How do I prevent one tenant from reading another tenant’s Store data?
Resolve tenant identity from trusted application context, make it the outer namespace and test semantically similar users across two tenants.
Does persisting a thread also preserve memory forever?
No. A thread can be compacted, expired or deleted. Durable user memory should be promoted separately with explicit scope and retention.
