Memory Storage Backends
BaseChatMessageHistory is the interface every storage backend implements, but picking the wrong backend — or ignoring LangGraph checkpointers entirely — will cost you in production. This article covers how to decide, configure, and operate each option.
Quick Reference
- →All backends implement BaseChatMessageHistory: add_messages(), messages, clear() — sync and async variants
- →InMemoryChatMessageHistory — development only, lost on restart
- →RedisChatMessageHistory — low-latency production; use redis_url= (not url=) and always set TTL
- →SQLChatMessageHistory — durable, queryable; add a cleanup job or the table grows indefinitely
- →LangGraph checkpointers (PostgresSaver, SqliteSaver) — use these instead when you need full agent state, interrupts, or branching
- →Factory function is the only swap point — the chain never imports the backend directly
- →Redis reads are sub-millisecond; SQL reads are typically 5–20ms with a connection pool
- →Without TTL on Redis, abandoned sessions accumulate — memory grows until the instance OOMs
Two Persistence Models: Checkpointers vs Chat History
LangChain gives you two separate persistence systems and they are not interchangeable. Understanding which one you need before picking a backend saves a painful migration later.
| Model | What it persists | When to use it |
|---|---|---|
| BaseChatMessageHistory | The message list for one conversation session — nothing else | You're using RunnableWithMessageHistory or managing history manually in a simple LCEL chain |
| LangGraph Checkpointer | Full agent state: messages + any state fields + interrupt points + branching history | You're using LangGraph agents, need human-in-the-loop interrupts, or need to resume a multi-step workflow |
If your agent is built with LangGraph, use a checkpointer — not RunnableWithMessageHistory. Wrapping a LangGraph agent with RunnableWithMessageHistory means you have two competing persistence layers. The checkpointer already stores messages as part of state; the chat history backend stores a duplicate. Pick one.
The rest of this article covers BaseChatMessageHistory backends. The LangGraph checkpointers section at the end covers the alternative path and when to take it.