Skip to main content
Persistence lets LangGraph applications keep useful information beyond a single graph run. It matters when an agent needs to continue a conversation, resume after an interruption, recover from a failure, or remember information across interactions. LangGraph provides two complementary persistence systems:
  • Checkpointers persist a thread’s graph state as checkpoints. Use them for short-term, thread-scoped memory, including conversation continuity, human-in-the-loop workflows, time travel, and fault tolerance.
  • Stores persist application-defined data outside the graph state. Use them for long-term, cross-thread memory, including user preferences, facts, and shared knowledge.
Most applications can use both: a checkpointer tracks the current thread, and a store tracks durable information across threads.

Quickstart

Compile your graph with a checkpointer, a store, or both:
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.store.memory import InMemoryStore

checkpointer = InMemorySaver()
store = InMemoryStore()

graph = builder.compile(checkpointer=checkpointer, store=store)

result = graph.invoke(
    {"messages": [{"role": "user", "content": "Hi, my name is Bob."}]},
    {"configurable": {"thread_id": "thread-1"}},
)
Agent Server handles persistence automatically When using the Agent Server, you do not need to implement or configure checkpointers or stores manually. The server handles persistence infrastructure behind the scenes.

Checkpointer vs. store

CheckpointerStore
PersistsGraph state snapshotsApplication-defined key-value data
ScopeA single threadAcross threads
Memory typeShort-term, thread-scoped memoryLong-term, cross-thread memory
Use forConversation continuity, human-in-the-loop, time travel, and fault toleranceUser preferences, facts, and shared knowledge
Access patternPass a thread_id in graph configRead and write items from nodes or application code
Full guideCheckpointersStores

Troubleshooting common issues

PostgresSaver: thread_id too long

When using PostgresSaver (or AsyncPostgresSaver), the thread_id is stored in a column with limited length. If your thread_id exceeds the column size, you will see a database error. Fix: Keep thread_id values under 255 characters. Use a UUID or hash if you need deterministic IDs:
import uuid

config = {"configurable": {"thread_id": str(uuid.uuid4())[:255]}}

MemorySaver does not persist between restarts

MemorySaver and InMemorySaver store checkpoints in RAM. When the process restarts, all checkpoints are lost. Fix: Use a persistent checkpointer for production:
  • PostgresSaver: PostgreSQL with async support
  • SqliteSaver: Local file-based storage for development

Checkpoints growing unboundedly

Over long conversations, checkpoints accumulate. This can increase latency and storage costs. Fix: Prune old checkpoints periodically or set a retention policy:
from langgraph.checkpoint.postgres import PostgresSaver

checkpointer = PostgresSaver.from_conn_string("postgresql://...")
checkpointer.setup()  # Creates tables with indexes
# Consider adding a cron job to delete checkpoints older than N days

State access from parent graph to subgraph

When a subgraph updates state, the parent graph may not see the changes immediately. This is because each subgraph manages its own checkpoint namespace. Fix: Use shared state via Store for data that needs to cross graph boundaries, or configure your subgraph to write to the parent checkpoint.

Next steps