TAI BUI
Back to curriculum
BuildPython

LangGraph: Stateful Graphs and Durable Execution

LangGraph is the 2026 reference for low-level stateful orchestration. The agent is a state machine: nodes are functions, edges are transitions, and state is immutable and checkpointed after every step. A failed run resumes exactly where it stopped.

TIME: ~75 minutesPREREQUISITES: Phase 14 · 01 (Agent Loop), Phase 14 · 12 (Workflow Patterns)

Learning Objectives

  • Describe LangGraph's core model: state machine with immutable state, function nodes, conditional edges, and post-step checkpoints.
  • Name the four capabilities the docs highlight: durable execution, streaming, human-in-the-loop, comprehensive memory.
  • Explain the three orchestration topologies LangGraph supports: supervisor, peer-to-peer (swarm), hierarchical (nested subgraphs).
  • Implement a stdlib state graph with immutable state, conditional edges, and a checkpoint/resume cycle.

The Problem

Agents and workflows share a failure mode: a 40-step run dies at step 38, and you want to resume from the last completed step (37) and redo only step 38, not start over. Libraries that treat state as an afterthought assume every run is fresh, which leaves operators bolting retries on from the outside.

LangGraph's design answer is to make state a first-class typed object, make mutations explicit, and persist a checkpoint after every node. Resuming means loading the latest checkpoint for the session and continuing from there.

Warm-up0/3
1. A routine agent run crashes on step 38 of 40 and nothing was saved along the way. What are you forced to do?Warm-up
2. In a routing workflow, what decides which specialist handles an incoming request?Warm-up
3. A Python function builds a new dict with `{**old, **changes}`. What happens to the dict `old`?Warm-up
Check: The Problem0/2
1. Why save a checkpoint after every node instead of once when the run finishes?Explain
2. Design A saves state only when a 40-step run ends. Design B saves after every node. Step 38 fails in both. What does each recover?Analyze

The Concept

A LangGraph agent is a state machine: a typed state object, functions that update it, and edges that decide which function runs next. The runtime saves the state after every step, and durable execution, human review, and the rest of this lesson follow from that one decision.

The graph

A graph is defined by:

  • State type. A typed dict (or Pydantic model) that every node reads. Nodes never modify it in place; they return updates, and the runtime builds the next state.
  • Nodes. Functions (state) -> state_update that do not touch the input state. A reducer (the merge rule that combines the current state with a node's update into a new state) applies each update after the node returns. The default reducer overwrites the updated keys; custom reducers can append to a list or add numbers instead. This is why state counts as immutable: every step produces a new state object rather than editing the old one.
  • Edges. Conditional or direct transitions between nodes.
  • Entry and exit. START and END sentinel nodes mark the boundary.

Take an agent with classify, refund, bug, sales, and done nodes. That is a routing workflow written as a graph.

Durable execution

After each node returns, the runtime serializes the state and writes it to a checkpointer (SQLite, Postgres, Redis, custom). When a run fails at step N, the runtime loads the last checkpoint (the state after step N-1) and re-runs from step N with exact state. When a run pauses after a node has finished, as at a human gate, the checkpoint already includes that node, so resume continues from the next one. The exact calls differ by library; the idea is always load latest checkpoint, then continue.

The LangGraph docs point to Klarna, Uber, and J.P. Morgan as production users where this matters. The graph shape alone isn't the claim. The graph shape plus checkpointing is, because together they make recovery cheap.

Streaming

Every node can yield partial output, and the graph streams per-node-delta events to the caller. UIs update while the graph is still running.

Human-in-the-loop

You can inspect and modify state between nodes. The usual implementation: pause before a critical node, surface the state to a human, accept their modifications, then resume. The checkpointer makes this easy because the state is already serialized.

Memory

Short-term memory lives within a run, as conversation history in state. Long-term memory spans runs, persisted through the checkpointer plus a separate long-term store. LangGraph connects to external memory systems (Mem0, custom) via tools.

Three topologies

  1. Supervisor. A central router LLM dispatches to specialist subagents. create_supervisor() in langgraph-supervisor does this, though in 2026 the LangChain team recommends going through tool calls directly for more control over context.
  2. Swarm / peer-to-peer. Agents hand off directly to each other through a shared tool surface. There is no central router.
  3. Hierarchical. Supervisors manage sub-supervisors, implemented as nested subgraphs.

Where this pattern goes wrong

  • Checkpoints too small. If you only checkpoint conversation turns, tool state and memory writes can't be recovered. Serialize the full state.
  • Non-deterministic nodes. Resume assumes a node's inputs produce the same state update. Random seeds, wall-clock time, and external API results have to be captured.
  • Over-use of conditional edges. When every edge is conditional, the graph is a state machine nobody can reason about. Prefer linear chains with occasional branches.
Check: The Concept0/26
1. What is a state graph?Define
2. What does a checkpointer do?Define
3. What is a reducer?Define
4. What is a conditional edge?Define
5. What is a subgraph?Define
6. What is durable execution?Define
7. What does streaming let a node do in LangGraph?Define
8. How does LangGraph split memory support?Define
9. Which of these is NOT one of the three topologies LangGraph supports?Define
10. What is a supervisor in LangGraph's topologies?Define
11. What is a swarm?Define
12. Why do nodes return updates instead of editing the state they receive?Explain
13. Why must nodes be deterministic for resume to work cleanly?Explain
14. A run fails inside a node, and another run pauses at a human gate after its node finished. Where does resume start in each case?Explain
15. How does the swarm topology differ from the supervisor topology?Explain
16. How does the hierarchical topology extend the supervisor topology?Explain
17. What goes wrong when checkpoints are too small?Explain
18. How does human-in-the-loop fit into LangGraph's design?Explain
19. Why does the lesson warn against making every edge conditional?Explain
20. Why is the graph shape alone not the claim behind LangGraph's production use at companies like Klarna, Uber, and J.P. Morgan?Explain
21. A node returns `{"step": 5}` and the state already holds `input` and `route`. What does the default reducer produce?Apply
22. After a crash and resume, a node returns a different result than the original run did. It reads the wall clock and calls an external API. What is the fix?Analyze
23. After a crash, the resumed run has the chat history, but a tool-created ticket id and a memory write are gone. What was the design mistake?Analyze
24. Which of these nodes breaks the rule that nodes must not touch the input state?Analyze
25. A 40-step job calls a paid API at step 25 and needs a human sign-off first. A crash after sign-off must not ask for it again. Which design fits?Design
26. You manage twelve specialist agents in three teams. Each team has its own lead, and one top-level lead coordinates the leads. Which topology fits?Design

Build It

code/main.py implements a stateful graph with the standard library only:

  • State is a typed dict with messages, step, route, output, human_approval.
  • Node is a callable that takes state and returns an update dict.
  • StateGraph holds nodes, edges, and conditional edges. Runner.run executes it, and passing resume_from plus a saved state resumes a run.
  • InMemoryCheckpointer stands in for a real backend such as SQLite. It deep-copies state after every node with save, and load_latest(session_id) returns the most recent snapshot. A real checkpointer would expose the same operations against a database.
  • The demo graph runs classify -> branch(refund / bug / sales) -> human gate -> send.

Run it:

python3 code/main.py

The trace shows the first run pausing at the human gate (after that node's checkpoint is saved), then a resume from the next node, send, with the approved state, which produces the final output.

Check: Build It0/8
1. In the demo's classify node, the input is "I want my money back, the app keeps crashing". Which route is set?Apply
2. In the demo, the input is "the CLI crashes on ctrl-c, please fix" and `human_approval` is False. What is in the checkpoint history when the first run pauses?Apply
3. After the demo resumes at send with approval, what does the final state's `output` hold for the input "the CLI crashes on ctrl-c, please fix"?Apply
4. The input is "Quote me your pricing, I also hit an error". Which route does classify choose?Apply
5. The demo pauses at the gate, saves an approved copy as `human_gate_reviewed`, then resumes at send. How many checkpoints does the session hold at the end?Apply
6. The same demo input is run with `human_approval` set to True from the start. What happens?Apply
7. The demo's first run paused at human_gate. Which node should `resume_from` name, and why?Apply
8. An operator resumes a paused run, but the trace shows classify and bug running again. What most likely went wrong?Analyze

Use It

  • LangGraph is the production-ready reference. Use create_react_agent, create_supervisor, or build your own graph.
  • AutoGen v0.4 (Lesson 14) is the actor-model alternative for high-concurrency scenarios.
  • Claude Agent SDK (Lesson 17) is a managed harness with a built-in session store.
  • Custom is the choice when you need exact control over state shape or checkpointer backend.
Check: Use It0/1
1. You want a managed harness with a built-in session store instead of wiring your own checkpointer. Which option fits?Design

Ship It

outputs/skill-state-graph.md generates a LangGraph-shaped state graph in any target runtime, with checkpointing and resume already wired in.

Author's Note

The graph is the easy part. The checkpoint is what you're really buying, so judge a design by one test: can a run die at any node and come back with nothing lost? That means serializing the full state rather than just the conversation, and capturing anything nondeterministic a node touches. On graph shape, keep it plain. A linear chain with an occasional branch is far easier to reason about than a web of conditional edges. And since the build in this lesson is stdlib, treat the library as a choice rather than a requirement: reach for LangGraph when its checkpointer backends and topologies solve a problem you have, and go custom when you need exact control over state shape.

Exercises

  1. Add a conditional edge from classify to end when classification confidence is below a threshold. Resume the run after a human sets route manually.
  2. Swap the in-memory checkpointer for a real SQLite one. Measure the per-step serialization overhead.
  3. Implement parallel edges: two nodes run concurrently and merge through a custom reducer. What does immutable state buy you here?
  4. Read the langgraph-supervisor reference and port the toy to create_supervisor. Compare the trace shapes.
  5. Add streaming so each node yields partial state while it runs. Print the deltas as they arrive.

Key Terms

TermWhat people sayWhat it actually means
State graph"Agent as state machine"Typed state + nodes + edges + reducers
Checkpointer"Persistence backend"Serializes state after every node; enables resume
Reducer"State merger"Function that combines current state with a node's update
Conditional edge"Branch"Edge chosen by a function of state
Subgraph"Nested graph"A graph used as a node inside another graph
Durable execution"Resume from failure"Restart at the last successful node with exact state
Supervisor"Router LLM"Central dispatcher for specialist subagents
Swarm"P2P agents"Agents hand off via shared tools; no central router

Further Reading

Code

Ships With