LangGraphLangGraph 1.2 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
38 small wins to finish your pathNext lesson →

Checkpointer: memory across turns

A checkpointer saves the state after every step. Give a run a thread_id and the next run on the same thread continues where the last one left off.

Last updated: 27 Sep, 2026 · LangGraph 1.2

Without a checkpointer every run starts from nothing. With one, a conversation carries across turns, which is what makes a chat feel like it remembers you.

Compiling with a checkpointer

python
from langgraph.checkpoint.memory import InMemorySaver

graph = builder.compile(checkpointer=InMemorySaver())
config = {"configurable": {"thread_id": "1"}}
graph.invoke(inputs, config)   # saved under thread "1"

This tiny graph has one node that always replies "ok". The piece to watch is the checkpointer, which saves the state so a second run on the same thread keeps the first run's messages. Build it one piece at a time.

The imports

Start with the imports: the graph pieces, the in-memory checkpointer, and the message types.

python
from langgraph.graph import MessagesState, StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver   # saves state per thread
from langchain.messages import HumanMessage, AIMessage

The reply node

Define one node. It ignores the input and returns a single AI message, which keeps the example small.

python
def reply(state):
    return {"messages": [AIMessage("ok")]}   # always answers "ok"

Building the graph

Build the graph and compile it with a checkpointer. That one argument is what turns on memory.

python
builder = StateGraph(MessagesState)
builder.add_node("reply", reply)
builder.add_edge(START, "reply")
builder.add_edge("reply", END)
graph = builder.compile(checkpointer=InMemorySaver())   # memory turned on
  • add_edge(START, "reply") runs the node first.
  • compile(checkpointer=InMemorySaver()) saves the state after every step.

Running two turns

Run two turns with the same thread_id and print how many messages the state holds.

python
cfg = {"configurable": {"thread_id": "1"}}                       # same thread = same memory
graph.invoke({"messages": [HumanMessage("hi")]}, cfg)           # turn 1
out = graph.invoke({"messages": [HumanMessage("again")]}, cfg)  # turn 2, same thread
print(len(out["messages"]))

The checkpointer in a run

The same pieces in one file.

Example
from langgraph.graph import MessagesState, StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver
from langchain.messages import HumanMessage, AIMessage

def reply(state):
    return {"messages": [AIMessage("ok")]}

builder = StateGraph(MessagesState)
builder.add_node("reply", reply)
builder.add_edge(START, "reply")
builder.add_edge("reply", END)
graph = builder.compile(checkpointer=InMemorySaver())

cfg = {"configurable": {"thread_id": "1"}}
graph.invoke({"messages": [HumanMessage("hi")]}, cfg)          # turn 1
out = graph.invoke({"messages": [HumanMessage("again")]}, cfg)  # turn 2, same thread
print(len(out["messages"]))

Why the count reached four

  • Turn 1 saved a human and an AI message under thread "1".
  • Turn 2 used the same thread_id, so it loaded those two, appended a new human and a new AI message, and ended with four.
  • A different thread_id would have started fresh with no history.

With and without a checkpointer

No checkpointerWith checkpointer
Each runStarts from nothingContinues its thread
MemoryNone across runsPer thread_id
NeedsNothingA thread_id in config

When you need a checkpointer

  • Any chat that should remember earlier turns.
  • Any run you want to pause and resume, which needs the state saved.
Watch out. InMemorySaver keeps checkpoints in RAM and loses them on restart. For anything real use SqliteSaver or PostgresSaver; the saving code is identical.
Try it yourself
  • Run turn 2 with a new thread_id. How many messages now?
  • Call graph.get_state(cfg) and read the saved messages.

You understood something today that you didn't yesterday.