Vocabulary for this course

The terms the chapters assume, in plain words. You can open this from any chapter.

checkpoint
A saved copy of the state after a step, stored under a thread so a run can resume or rewind.
compile
The step that checks a graph's connections and turns it into something that can be run.
conditional edge
A rule that reads the state and names which node runs next.
edge
A rule saying which node runs after the current one finishes.
entry point
The declared first node of a graph, marked by an edge from the start.
graph
A workflow drawn as nodes joined by edges, where the path can branch and loop.
interrupt
A planned pause before a node runs, so a person can approve, reject or edit first.
node
A function that reads the state and returns only the keys it changed.
reducer
A function that decides how an update is combined with the old value of one state key.
state
The shared record passed between nodes, holding every value the workflow needs to continue.
subgraph
A graph mounted inside another as a single node, with its own slice of state.
supervisor
A node that reads the state and chooses which specialist worker runs next, rather than answering itself.
thread
A named run whose checkpoints are stored together, so it can be listed, resumed or branched.

LangGraph from the ground up

Checkpoints and resumption

A checkpoint is the state after every step, saved under a thread id. It turns a crashed run into something you can continue, and a finished run into something you can rewind.

Part 5 of 10

Intermediate16 min readBack to Courses

A thread is a run you can name

Every invocation carries a thread_id. The checkpointer stores the state after each node under that id, so the next invocation with the same id starts from the last saved step rather than from the beginning.

That is what makes a long workflow practical. A request that takes thirty seconds and fails at step seven does not have to start again; it resumes at seven with the state it had.

A worked example: a refund workflow runs under thread order-1024. Steps one to six write a request, validate it, compute the amount and draft a message. Step seven calls the payment API and the process restarts. The next run loads the step-six checkpoint and runs the payment node with the amount and message in the state. Whether that is one refund or two depends on an idempotency key.

What gets saved

The state, the node that produced it, and the step number. Not the model’s internal state, not the tool’s connection. Everything the next node needs must be in the state, which is the same rule that made the graph resumable in the first place.

This is why payloads in the state are a liability. A checkpoint that carries a hundred pages of retrieved text is slow to write and expensive to store; a checkpoint that carries ids is small and fast.

A checkpoint is more than the values. It records which node produced them and which node comes next, which is what makes resumption a continuation rather than a replay. The model’s internal state, a database cursor, an open websocket — none of that is saved. If the next node needs it, it has to be in the state or recreated from it. The step number is what makes the history listable.

A checkpointer in LangGraph

from langgraph.checkpoint.memory import MemorySaver

graph = builder.compile(checkpointer=MemorySaver())

config = {"configurable": {"thread_id": "order-1024"}}
graph.invoke({"question": "Where is my order?"}, config)

# Later, same thread: continues from the saved state.
state = graph.get_state(config)
print(state.values, state.next)

Save after every step

Run the graph, inspect the snapshots, then delete the last one and resume. The run should continue from the previous step, not the start.

Output
Click "Run" to execute your code

Time travel is the same mechanism

Because every step is stored, you can list the history of a thread, load an earlier checkpoint, and continue from there. That is not a debugging curiosity: it is how you test an alternative route without re-running the expensive part.

It also makes “what did the state look like when it went wrong” answerable after the fact, which is the question that matters most in an incident review.

A worked rewind: list the thread, load the checkpoint after the outline step, change the outline, and invoke. The graph continues from the node after that checkpoint with the new outline; the later steps run again and produce a different draft. The original run is untouched, which is what makes this a branch rather than an edit. Loading a checkpoint does not delete the later ones; they remain as the original branch.

Use one thread per user-visible task, not per user. A thread that spans a whole session becomes a history nobody can read; one per task can be listed, resumed and deleted.

Checkpoint after the side effect?

A checkpoint saves the state after a node returns. If the node sent an email and the process died before the checkpoint was written, resumption runs the node again and sends a second email. That is the classic at-least-once problem, and the checkpointer does not solve it.

The fix is an idempotency key in the state: the email provider deduplicates on it, so the second call is a no-op. The key is generated before the side effect and saved with the state, not after. Any node that talks to the outside world needs one.

Storage is a real decision

An in-memory checkpointer is fine for a demo and useless across restarts. Postgres or Redis make a run survive a deploy, which is what “resumable” has to mean in production.

Retention matters too. Checkpoints accumulate, and a thread that is never cleaned up is a growing table. Decide how long a finished run is worth keeping before the first deployment, not after the table is large.

Retention is a data decision as well as a storage one. Checkpoints contain the user’s question, the retrieved passages and the draft, so they inherit whatever personal data the workflow handles. Decide how long a finished thread is kept, encrypt the store, and delete on request. A checkpoint table nobody prunes is a copy of your users’ data with no owner.

Rewind and branch

Run the workflow, rewind to the second checkpoint, and change the outline. The rest of the run continues from the new value — a different branch from the same history.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

What does a thread id identify?