LangChain/Memory & Middleware
★ OverviewIntermediate9 min

Conversation Memory

How LangChain handles conversation memory. RunnableWithMessageHistory wraps any chain to automatically persist and inject session history — no magic classes, just explicit messages.

Quick Reference

  • RunnableWithMessageHistory wraps your chain and manages history automatically per session_id
  • BaseChatMessageHistory is the interface — InMemoryChatMessageHistory for dev, Redis/SQL for prod
  • History is injected via MessagesPlaceholder in your prompt
  • Old classes (ConversationBufferMemory, ConversationChain) are fully deprecated since 0.3
  • You never touch the message list directly — RunnableWithMessageHistory does it for you

How LangChain Memory Works

In LangChain, memory means keeping track of the conversation across multiple turns. The recommended approach is RunnableWithMessageHistory — it wraps your chain and automatically loads past messages before each call, then saves the new exchange after. You write your chain normally, and memory is handled outside of it.

No hidden state

Unlike the old memory classes, RunnableWithMessageHistory doesn't hide state inside the chain. The history lives in a separate storage object (BaseChatMessageHistory). Your chain stays pure — it just receives a message list as input.

Do not use legacy memory classes

ConversationBufferMemory, ConversationSummaryMemory, ConversationBufferWindowMemory, and ConversationChain are all deprecated since LangChain 0.3. They don't work with LCEL. Replace with RunnableWithMessageHistory.