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.
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.
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_updatethat 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.
STARTandENDsentinel 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
- Supervisor. A central router LLM dispatches to specialist subagents.
create_supervisor()inlanggraph-supervisordoes this, though in 2026 the LangChain team recommends going through tool calls directly for more control over context. - Swarm / peer-to-peer. Agents hand off directly to each other through a shared tool surface. There is no central router.
- 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.
Build It
code/main.py implements a stateful graph with the standard library only:
Stateis a typed dict withmessages,step,route,output,human_approval.Nodeis a callable that takes state and returns an update dict.StateGraphholds nodes, edges, and conditional edges.Runner.runexecutes it, and passingresume_fromplus a saved state resumes a run.InMemoryCheckpointerstands in for a real backend such as SQLite. It deep-copies state after every node withsave, andload_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.
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.
Ship It
outputs/skill-state-graph.md generates a LangGraph-shaped state graph in any target runtime, with checkpointing and resume already wired in.
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
- Add a conditional edge from
classifytoendwhen classification confidence is below a threshold. Resume the run after a human setsroutemanually. - Swap the in-memory checkpointer for a real SQLite one. Measure the per-step serialization overhead.
- Implement parallel edges: two nodes run concurrently and merge through a custom reducer. What does immutable state buy you here?
- Read the
langgraph-supervisorreference and port the toy tocreate_supervisor. Compare the trace shapes. - Add streaming so each node yields partial state while it runs. Print the deltas as they arrive.
Key Terms
| Term | What people say | What 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
- LangGraph overview: the reference docs
- langgraph-supervisor reference: supervisor pattern API
- AutoGen v0.4, Microsoft Research: actor-model alternative
- Claude Agent SDK overview: session store and subagents