LangChain LangGraph Checkpoints
A graph run normally forgets everything when it ends. A checkpoint saves the state after every step, so a conversation can continue later, a crashed job can resume, and a human can pause the flow to review an action. Checkpoints turn a short-lived script into a durable application.
Video Game Save Point Analogy
A game saves progress at checkpoints. A player who quits tonight returns tomorrow at the same spot instead of starting over. LangGraph does the same for your workflow.
Step 1 → [save] → Step 2 → [save] → Step 3 → [save]
↑
crash or pause here
|
Resume from the last save, not from the start
Adding a Checkpointer
A checkpointer is the storage that holds the saved states. The in-memory version suits learning and tests.
from langgraph.checkpoint.memory import InMemorySaver
checkpointer = InMemorySaver()
graph = builder.compile(checkpointer=checkpointer)Threads: One Conversation, One ID
A thread id labels one run history. Calls with the same thread id continue the same conversation. A new thread id starts fresh.
config = {"configurable": {"thread_id": "customer-17"}}
graph.invoke({"messages": [{"role": "user", "content": "My name is Kabir."}]}, config)
out = graph.invoke({"messages": [{"role": "user", "content": "What is my name?"}]}, config)
print(out["messages"][-1].content) # Your name is Kabir.The second call never repeats the name. The checkpointer restores earlier messages automatically, so you no longer manage history by hand.
Inspecting Saved State
snapshot = graph.get_state(config)
print(snapshot.values) # current state
print(snapshot.next) # nodes waiting to run
for past in graph.get_state_history(config):
print(past.config["configurable"]["checkpoint_id"])The history acts like a time machine. You can read old states, find where a bug appeared, and replay from an earlier point.
Durable Storage for Real Apps
Memory storage vanishes when the program stops. Database checkpointers survive restarts.
- SQLite suits local tools and small apps.
- PostgreSQL suits production services.
from langgraph.checkpoint.sqlite import SqliteSaver
with SqliteSaver.from_conn_string("checkpoints.db") as saver:
graph = builder.compile(checkpointer=saver)
graph.invoke(inputs, config)Install the matching package, such as langgraph-checkpoint-sqlite, before importing it.
Human-in-the-Loop with Interrupts
Some actions need a person's approval. The interrupt function pauses the graph and shows a message to the reviewer. The checkpoint stores everything, so the pause can last seconds or days.
[Draft email] → [Ask approval] ── pause ──→ Human decides
|
+-------------------------+
v
[Send email] or [Cancel]
from langgraph.types import interrupt, Command
def approval(state):
decision = interrupt({
"question": "Send this email?",
"draft": state["draft"],
})
return {"approved": decision == "yes"}Resuming After a Pause
first = graph.invoke({"draft": "Hello team..."}, config)
print(first["__interrupt__"]) # shows the question to the reviewer
final = graph.invoke(Command(resume="yes"), config)The Command object carries the human answer back into the paused node. The node continues exactly where it stopped.
Use Cases
- Chatbots that remember users across visits.
- Approval flows for payments, emails, and data changes.
- Long research jobs that survive server restarts.
- Debugging by replaying earlier states.
Good Practices
- Choose thread ids tied to a user or a conversation.
- Keep state small and serializable.
- Delete old threads on a schedule to protect privacy and storage.
- Never store secrets inside state.
Real-World Scenario
A legal research tool takes ten minutes to collect and summarize documents. Midway through a run, the server restarts. Without checkpoints, the whole job starts over. With a database checkpointer, the graph resumes from the last saved step and finishes the work. The same tool pauses before sending a summary to a client. A lawyer reads the draft, approves it, and the graph continues the next morning. Saved state made both cases safe.
Practice Tasks
- Compile a graph with InMemorySaver and hold a three-turn conversation on one thread id.
- Switch to a new thread id and confirm that the memory resets.
- Print the state history and count how many checkpoints your run created.
- Add an interrupt before a final step and resume it with Command.
Planning Thread IDs
A thread id works like a folder name for one conversation. Combine the user id with a conversation number, such as user42-chat3, so each person can keep several separate chats. Reuse the same id to continue a talk, and create a new id to start over. Store the id on the client side or in your user table. Careful naming prevents two users from sharing the same memory by accident.
Key Points
- Checkpoints save graph state after every step.
- Thread ids separate conversations.
- Database checkpointers survive restarts.
- interrupt pauses for human review, and Command resumes the run.
- State history supports debugging and replay.
