What is MemorySaver?
MemorySaver is LangGraph's built-in in-memory checkpointer. When you compile a StateGraph with checkpointer=MemorySaver(), LangGraph serialises the full graph state after every node execution and stores it as a checkpoint keyed by (thread_id, checkpoint_id). This enables three capabilities: resuming after an interrupt, replaying past states for debugging, and implementing human-in-the-loop workflows where the graph pauses and waits for external input.
Each thread_id represents an independent conversation or workflow run. You supply the thread via config={"configurable": {"thread_id": "user-42"}}. MemorySaver keeps all checkpoints for all threads in memory as a nested dict — get_state(config) retrieves the latest snapshot, get_state_history(config) returns the full timeline. This makes it excellent for step-through debugging and for building UIs that show workflow replay.
MemorySaver is strictly single-process. It does not share state across workers or survive a restart. For deployment, migrate to AsyncPostgresSaver (pip install langgraph-checkpoint-postgres) or AsyncSqliteSaver. The API is identical — just swap the checkpointer argument. The checkpoint schema is stable across versions, so data created during development can be migrated to a persistent store without schema changes.
When to Use
You're developing or testing graph workflows. Use MemorySaver for rapid iteration.
Use Cases
- • Development testing
- • Graph prototyping
- • Interrupt/resume testing
- • State debugging
- • Local workflows
- • Quick iteration
Key Features
- ✓ In-memory state
- ✓ Thread history
- ✓ State snapshots
- ✓ Fast
- ✓ No external DB
- ✓ Easy debugging
When NOT to Use
For production—use PostgresSaver. For long-running workflows.
Notes
Not safe across multiple processes or async workers
MemorySaver stores checkpoints in a plain Python dict. Multiple uvicorn/gunicorn workers each have their own memory — thread A in worker 1 cannot see the state from worker 2. For any real deployment, use AsyncPostgresSaver or AsyncSqliteSaver. The switch is one line: replace MemorySaver() with the async saver.
thread_id must be unique per logical conversation
Reusing the same thread_id for different users or sessions means their states collide. Use a UUID or user-session identifier. In multi-tenant systems, prefix with the user ID: f"{user_id}:{session_id}". MemorySaver does not enforce uniqueness — a collision silently overwrites the existing thread.
get_state_history enables time-travel debugging
Call compiled.get_state_history(config) to retrieve every checkpoint saved for a thread, from newest to oldest. You can rewind to any prior state by passing that checkpoint's config back into invoke(). This is how LangGraph Studio's step-back feature works — and you can replicate it in your own debugging tooling.
Memory grows unbounded — watch process RSS in long tests
Every node execution appends a checkpoint. Long-running tests or load tests against a MemorySaver-backed graph will eventually exhaust heap memory. Use a TTL dict or periodically call checkpointer.delete_checkpoints() if you run many threads during testing.
Import
from langgraph.checkpoint.memory import MemorySaver
Usage Examples
Basic Checkpointing
from langgraph.checkpoint.memory import MemorySaver
checkpointer = MemorySaver()
compiled = graph.compile(checkpointer=checkpointer)
config = {'configurable': {'thread_id': '1'}}
result = compiled.invoke(input, config=config)
Human-in-the-loop Interrupt and Resume
from langgraph.checkpoint.memory import MemorySaver
# Graph with an interrupt before the "human_review" node
checkpointer = MemorySaver()
compiled = graph.compile(
checkpointer=checkpointer,
interrupt_before=["human_review"],
)
config = {'configurable': {'thread_id': 'session-1'}}
# First invocation stops before human_review
compiled.invoke({"task": "review this"}, config=config)
# Later: resume after human approves
compiled.invoke(None, config=config)
Inspect Checkpoint History
# Inspect the full checkpoint history for a thread
config = {'configurable': {'thread_id': 'session-1'}}
state_history = list(compiled.get_state_history(config))
for checkpoint in state_history:
print(checkpoint.config["configurable"]["checkpoint_id"])
print(checkpoint.values) # full state at that step
Common Pitfalls
❌ Use MemorySaver in production
✅ Use PostgresSaver for production
Related LangChain References
Browse the full LangChain API reference index to explore more classes, methods, and decorators, or start with the LangChain introduction tutorial for end-to-end context on building with MemorySaver and the wider framework.
MemorySaver FAQ
What is MemorySaver in LangChain?
In-memory checkpointing for LangGraph. MemorySaver is LangGraph's built-in in-memory checkpointer. When you compile a StateGraph with checkpointer=MemorySaver(), LangGraph serialises the full graph state after every node execution and stores it as a checkpoint keyed by (thread_id, checkpoint_id). This enables three capabilities: resuming after an interrupt, replaying past states for debugging, and implementing human-in-the-loop workflows where the graph pauses and waits for external input. Each thread_id represen…
Which package provides MemorySaver?
DevShelfHub documents MemorySaver from the langgraph package. Pin your installed LangChain version and match imports to the snippet on this page.
When should I use MemorySaver?
You're developing or testing graph workflows. Use MemorySaver for rapid iteration.
When should I avoid using MemorySaver?
For production—use PostgresSaver. For long-running workflows.
How do I import MemorySaver in Python?
from langgraph.checkpoint.memory import MemorySaver
Where can I explore more LangChain API reference pages?
Open the LangChain API reference index on DevShelfHub to browse classes, methods, and decorators, each with runnable examples, parameters, common mistakes, and cross-links.