Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Workflow:Langchain ai Langgraph Persistence and Memory Setup

From Leeroopedia
Knowledge Sources
Domains LLM_Ops, Data_Persistence, Agent_Orchestration
Last Updated 2026-02-11 15:00 GMT

Overview

End-to-end process for configuring LangGraph's persistence layer using checkpoint savers for execution state and stores for cross-thread long-term memory.

Description

This workflow covers setting up LangGraph's dual persistence system: checkpointers for saving graph execution state (enabling resume, replay, and time-travel debugging) and stores for persistent key-value data that spans across threads (enabling long-term memory, user profiles, and shared knowledge). Checkpointers capture the full channel state at each superstep, while stores provide a hierarchical namespace-based key-value interface with optional semantic search via embeddings. The combination enables agents with both short-term working memory (checkpoints) and long-term persistent memory (stores).

Usage

Execute this workflow when building agents that need conversational memory across interactions, durable execution that survives failures, time-travel debugging to inspect past states, or long-term knowledge persistence that spans across different conversation threads. This is essential for any production LangGraph deployment where state must survive process restarts.

Execution Steps

Step 1: Choose a Checkpoint Backend

Select the appropriate checkpoint saver based on your deployment requirements. LangGraph provides `InMemorySaver` for development, `SqliteSaver` for lightweight persistent storage, and `PostgresSaver` for production-grade persistence. Each implements the `BaseCheckpointSaver` protocol with `get_tuple()`, `put()`, `list()`, and `put_writes()` operations.

Key considerations:

  • `InMemorySaver`: No persistence, data lost on restart; suitable for testing only
  • `SqliteSaver`: File-based persistence; good for single-process deployments
  • `PostgresSaver`: Full ACID compliance, concurrent access; production recommended
  • Each has both sync and async variants (e.g., `AsyncSqliteSaver`, `AsyncPostgresSaver`)

Step 2: Initialize the Checkpointer

Create and configure the checkpoint saver instance. For database-backed savers, establish the connection and run the setup step to create required tables. The checkpointer uses a serializer (default: `JsonPlusSerializer`) to encode state for storage.

Key considerations:

  • Call `setup()` once per database to create checkpoint tables
  • Use connection pools for Postgres in production (via `psycopg_pool`)
  • `from_conn_string()` factory methods simplify connection setup
  • Context managers (`with` / `async with`) handle connection lifecycle

Step 3: Compile Graph with Checkpointer

Pass the checkpointer to `compile()` when building the graph, or to `create_react_agent()` for prebuilt agents. This enables automatic state persistence at each superstep of execution. Every `invoke()` or `stream()` call must include a `thread_id` in the config to identify the execution thread.

Key considerations:

  • The `thread_id` is the primary key for checkpoint storage
  • Reuse the same `thread_id` for multi-turn conversations
  • Use unique `thread_id` values for independent execution threads
  • The `checkpoint_ns` allows namespace isolation within a thread

Step 4: Configure a Store for Long-Term Memory

Set up a `BaseStore` implementation for persistent data that spans across threads. Stores use hierarchical namespaces (tuples of strings) to organize data, and support `get()`, `put()`, `search()`, and `delete()` operations. Optionally configure embedding-based semantic search by providing an index configuration with dimensions and an embedding function.

Key considerations:

  • Stores are independent of checkpointers; they serve different purposes
  • Namespace hierarchy enables per-user, per-org, or per-topic scoping
  • Semantic search requires embedding configuration (`dims`, `embed`, `fields`)
  • TTL configuration enables automatic expiration of stale data
  • Pass the store to `compile(store=...)` to make it available in graph nodes

Step 5: Access State and Memory in Nodes

Within graph nodes, access the checkpoint state via the state parameter and the store via `InjectedStore` annotations on tool parameters or by using the config. Use `get_state()` on the compiled graph to inspect the current state externally. Use `update_state()` to modify state from outside the graph.

Key considerations:

  • Nodes receive current state automatically as their first parameter
  • Tools access the store via `InjectedStore` annotation for dependency injection
  • `graph.get_state(config)` retrieves the latest checkpoint for a thread
  • `graph.update_state(config, values)` modifies state externally
  • `graph.get_state_history(config)` lists all checkpoints for time-travel

Step 6: Manage Thread Lifecycle

Handle thread cleanup by deleting old checkpoints with `delete_thread()`. List checkpoints for auditing with `list()`. Fork execution from a past checkpoint by providing a specific `checkpoint_id` in the config. This enables time-travel debugging, branching conversations, and state management.

Key considerations:

  • `list(config)` returns checkpoints newest-first for a thread
  • Provide `checkpoint_id` in config to resume from a specific past state
  • `delete_thread(thread_id)` removes all checkpoints for cleanup
  • Each checkpoint has metadata including `source`, `step`, and `parents` for tracing

Execution Diagram

GitHub URL

Workflow Repository