LangGraph internals: state, reducers, super-steps, and time travel
Beneath LangGraph's nodes and edges is a precise runtime model — immutable state merged by reducers, executed in super-steps, checkpointed after each one. Understanding it is what makes LangGraph predictable.
The earlier LangGraph posts covered the what and the why — nodes, edges, state, and when to reach for a graph. This one goes under the hood, because LangGraph's real value is its runtime model, and knowing it is what turns 'it works' into 'I know exactly what it will do'.
State is immutable; reducers merge updates
Nodes don't mutate state in place. A node receives the current state and returns an update — a new, partial state — and LangGraph merges it in. How it merges is up to you: for each field you can define a reducer, a function that combines a node's update with the existing value. A field with no reducer is overwritten (last write wins); a field with an append reducer accumulates. This is precisely what lets multiple nodes run at once and combine their results without clobbering each other.
from typing import Annotated
from operator import add
from typing_extensions import TypedDict
class State(TypedDict):
# each node returns {'messages': [...]}; the reducer appends instead of overwriting
messages: Annotated[list, add]
count: int # no reducer -> last write winsThe super-step: one iteration over the graph
Execution happens in super-steps. A super-step is a single iteration over the graph's nodes: nodes that run in parallel belong to the same super-step, and nodes that run sequentially belong to separate ones. One graph.invoke() is a single run — a sequence of super-steps, one per layer of nodes — the direct analogue of one Runner.run() in the OpenAI Agents SDK. Within each super-step the active nodes run in parallel, and the reducers merge their updates into State before the next super-step begins.
The five steps to build a graph
Before you ever run an agent, your code does five things:
- Define the State class — the shape of what flows through the graph, with reducers on the fields that need them.
- Start the graph builder — a StateGraph over that state.
- Add nodes — the units of work.
- Add edges — including conditional ones, which choose what runs next.
- Compile the graph — into a runnable, optionally with a checkpointer.
from langgraph.graph import StateGraph, START, END
builder = StateGraph(State) # 2. graph builder
builder.add_node('work', do_work) # 3. nodes
builder.add_edge(START, 'work') # 4. edges
builder.add_edge('work', END)
graph = builder.compile(checkpointer=saver) # 5. compileCheckpointing: memory and time travel
A checkpointer saves a snapshot of State after every super-step, and that one feature buys a lot:
- MemorySaver keeps checkpoints in memory — fast, but gone on restart.
- SqliteSaver writes them to a file that survives restarts (with Postgres and other backends for production).
- thread_id is the config key that saves and reloads a conversation — pass the same one to continue where you left off.
- get_state and get_state_history let you inspect the current snapshot and every past one.
- Time travel — rerun the graph from any earlier checkpoint_id, to branch from or replay a past state.
from langgraph.checkpoint.memory import MemorySaver
graph = builder.compile(checkpointer=MemorySaver())
cfg = {'configurable': {'thread_id': 'user-42'}}
graph.invoke({'messages': [msg]}, cfg) # snapshot saved after each super-step
graph.get_state(cfg) # the current snapshot
list(graph.get_state_history(cfg)) # every snapshot
# time travel: resume from an earlier checkpoint
graph.invoke(None, {'configurable': {'thread_id': 'user-42', 'checkpoint_id': earlier}})Why this matters
This runtime model is what makes LangGraph durable and debuggable rather than just another agent library. Reducers give you safe parallel merges; super-steps give the execution a legible structure; checkpoints give you resumable runs, human-in-the-loop pauses, and the ability to inspect or rewind any step. It's the machinery behind the 'explicit, durable, stateful control' the concept post promised — and the reason LangGraph is the layer to reach for when reliability matters.
Nodes and edges are the drawing. Immutable state, reducers, super-steps, and checkpoints are the engine — and the engine is why a LangGraph agent is one you can actually trust in production.