We've been running LangGraph in production for about 3 months now, scaling from a single POC to 5 engineers building complex agent workflows. The main bottleneck was state handling under concurrent load.
Our core issue: using the default in-memory state with concurrent users led to weird state corruption and lock contention. Debugging was a nightmare.
We solved it by:
* Moving state persistence to an external Postgres backend. We forked the SQL store example and heavily optimized it for our schema.
* Implementing a Redis-based locking mechanism for critical state updates, which we layered on top of the SQL store.
* Moving all our checkpointing to be explicit and versioned, rather than relying on automatic saves.
The key lesson: treat LangGraph's state as a persistent database from day one, not a temporary cache. The out-of-the-box options don't hold up for real multi-user systems.
We're now seeing reliable performance for ~50 concurrent workflows. Next challenge is monitoring the graph execution flow itself—built-in observability is minimal.
> "Moving all our checkpointing to be explicit and versioned, rather than relying on automatic saves."
That's the right call. The default auto-save behavior works fine for a single session but becomes a liability under concurrency. We've seen similar patterns with Durable Objects and Temporal workflows. The versioned checkpointing is essentially an optimistic concurrency control pattern applied to graph state. One thing to watch for: if your explicit checkpoints are too coarse, you lose the ability to replay partial failures. We ended up with a hybrid approach where we version at the node level but only persist to Postgres after a full subgraph completes. That cuts the I/O overhead while still giving us granular replays.
On the monitoring front, we built a custom exporter that hooks into the LangGraph execution loop and emits OpenTelemetry spans for each node invocation. We attach the checkpoint version and a trace ID from the user's session. That lets us correlate execution flow with state changes in Postgres. The built-in observability is indeed minimal, but the graph structure makes it easier to instrument than you'd think. We pipe the spans into Honeycomb, and the heatmap of node durations alone caught three bottlenecks in the first week.
Are you doing anything with the checkpoint versions beyond debugging? We've found them useful for A/B testing different agent strategies on the same input.
Data over dogma