How to manage state persistence in Langgraph workflows

Hello everyone,

I’m working on my first Langgraph agent that runs on AWS Lambda. I need help with storing conversation state between different function calls. Previously with basic LangChain, I used DynamoDBChatMessageHistory which worked great.

What I want to achieve:

  1. Save the complete workflow state to DynamoDB when Lambda execution finishes
  2. Load previous state when the same conversation continues in a new Lambda call

I tried using checkpointers but they seem to store way more data than I need. My workflow is straightforward (START → NodeA → NodeB → NodeC → END) but checkpointers create saves after each step instead of just at the end.

I’m wondering about the best approach:

  1. Should I create a custom checkpointer that only saves when reaching the final node?
  2. Would it be better to skip checkpointers completely and just save the messages array to DynamoDB manually?
  3. Are there any built-in settings I missed that would only checkpoint the final state?

Any advice would be helpful!

Skip checkpointers completely for this. I ran into the same thing building a customer support agent that had to handle Lambda timeouts.

Checkpointers are built for complex workflows that might crash halfway through. Your linear flow doesn’t need that bloat.

Here’s what works: grab the conversation state right before your END node and push it to DynamoDB in one write. I serialize the messages array plus whatever workflow variables I need.

When Lambda starts up, I check DynamoDB first. If there’s existing state for that conversation ID, I rebuild the graph’s initial state with those messages and variables.

Key thing - keep your state object lightweight. Don’t save the whole graph state or internal LangChain stuff. Just the essential data to continue the conversation.

I use something simple like:

{
  "conversation_id": "abc123",
  "messages": [...],
  "current_step": "completed",
  "user_context": {...}
}

This cut my DynamoDB costs by 80% vs checkpointers and killed all the complexity around filtering intermediate saves.

i’d say option 2 is the way to go for lambda stuff. checkpointers are a hassle if all u need is to keep the convo going. i did something similar where i just took the message history at the end and saved it all in one go. way simpler than dealing with checkpointer issues.

I ran into the same thing building a multi-step document processing agent on Lambda. The built-in checkpointers are way too much for simple linear workflows like yours. Here’s what worked for me: I kept the checkpointer but made it only save at specific points using conditional logic in a custom class. You can inherit from the base checkpointer and override the put method to filter out intermediate states based on node names or custom flags. But honestly, for your straightforward workflow, just managing the conversation state manually might be easier. I pull the messages and any custom state variables at the end of my workflow and dump them into a single DynamoDB item with the conversation ID as the key. When Lambda cold starts, I rebuild the initial state by loading that data. The big win is you control exactly what gets saved and when. Just make sure you handle state reconstruction properly when resuming conversations.