State Management (in LangGraph)
State is the heart of LangGraph. Nodes don't call each other or pass arguments around — they all read from and write to one shared state object. Understanding how state is defined, updated, and persisted is what separates a graph that works from one that mysteriously loses data or overwrites itself.
💡 In one line: LangGraph state is a shared, typed object that every node reads and updates — with reducers deciding how updates merge.
What is State?
State is a typed, shared object that flows through the graph. Each node receives the current state and returns a partial update; LangGraph merges that update into the state and passes it on. Nodes are decoupled — they communicate only through state.
Defining State
Usually a TypedDict (or a Pydantic model / dataclass):
The schema defines what the graph carries.
Nodes Return Partial Updates
A node returns only the keys it changes — not the whole state:
This is the most common source of confusion: return partial updates, not a full copy.
Reducers (Critical)
A reducer decides how an update merges into the existing value:
- Default — overwrite the old value.
Annotated[list, add]— append (the classic formessages).- Custom — any merge function you define.
Get this wrong and nodes silently overwrite each other — the classic LangGraph bug.
The Update Cycle
MessagesState
For chat agents, LangGraph ships a prebuilt MessagesState with a messages key and the append reducer already configured — the standard base for conversational graphs.
Persistence: Checkpointers
A checkpointer saves the state at every step, keyed by thread_id:
InMemorySaver— development.SqliteSaver— local persistence.PostgresSaver— production.
This gives you durability (survive a restart), resumability, human-in-the-loop pauses, and time travel.
Threads vs. Long-Term Store
- Checkpointer (
thread_id) — state for one conversation. - Store (namespace) — facts across all conversations for a user.
Keep thread_id and user_id distinct — mixing them up is the classic production mistake.
Managing State Size
Message lists grow unbounded, and long contexts degrade quality. Fix with trimming (trim_messages), summarising older turns, or keeping large artefacts out of state (store a reference, not the whole file).
Time Travel
Because every step is checkpointed, you can replay a past run or branch an alternate history from any step — a genuinely powerful debugging tool.
Best Practices
- Keep the state schema minimal and typed.
- Use reducers deliberately — especially append for
messages. - Return partial updates from nodes.
- Use a durable checkpointer in production; trim or summarise long histories.
Summary
- State is a shared, typed object; nodes communicate only through it.
- Nodes return partial updates, and reducers decide overwrite vs. append.
MessagesStateis the prebuilt base for chat agents.- Checkpointers persist state per
thread_id— enabling durability, HITL, and time travel. - Keep state small: trim, summarise, and store references rather than blobs.Â