This document outlines heuristics and warning signs that indicate when your LangGraph state may be too large or messy to manage effectively.
- Sign: Heavy reliance on nested dictionaries/lists (
state["a"]["b"]["c"]). - Why it matters: Difficult to track updates, read, and debug.
- Heuristic: More than 2β3 levels of nesting or needing custom update logic indicates excessive complexity.
- Sign: Holding entire HTML pages, PDFs, DOM trees, or long histories in state.
- Why it matters: Slows down serialization between nodes and increases memory usage.
- Heuristic: If serialization takes >100ms or state exceeds ~1MB, store data externally and keep references/IDs in state.
- Sign: Node A expects node B to produce a very specific state structure.
- Why it matters: Tight coupling makes refactoring difficult and error-prone.
- Heuristic: If changing one nodeβs output breaks others, the state is too coupled.
- Sign: State dumps are too long or unreadable; logs are avoided.
- Why it matters: Makes debugging workflows harder and slower.
- Heuristic: If a printed state isnβt human-readable at a glance, simplify it.
- Sign: Many nodes mutate the same keys with no clear ownership.
- Why it matters: Creates hidden dependencies and bugs.
- Heuristic: If multiple nodes write to the same key, introduce conventions or encapsulate updates.
- Sign: Node logic checks many unrelated keys to operate.
- Why it matters: Increases fragility and reduces reusability.
- Heuristic: More than 3β5 unrelated state dependencies per node is a sign to refactor.
- Modularize: Use sub-objects (e.g.,
state["browser"],state["user"]). - Externalize Heavy Data: Offload to Redis, S3, or a vector DB and store pointers.
- Immutable Updates: Avoid in-place mutations where possible.
- Schema Enforcement: Use Pydantic or typed dicts.
- Debug View: Include
state["trace"]orstate["log"]for human-readable traces.