Back to roadmaps langgraph Course

State Persistence with Graph Checkpointers

A Checkpointer is a database layer that automatically saves a snapshot of the graph's state after every node executes. Checkpointers enable chat history tracking, error recovery, and human-in-the-loop workflows.


1. How Checkpointing Works

When you invoke a graph with a configuration containing a unique thread_id, LangGraph tracks its progress:

  1. Node 1 executes: State updates are written.
  2. Checkpoint created: The checkpointer writes the full State payload along with metadata to storage.
  3. Node 2 executes: If it fails, you can reload the checkpoint from Step 2 and resume.

2. Choosing Checkpointer Engines

  • MemorySaver: Stores checkpoints in server RAM. Ideal for local development, testing, and prototyping, but resets when the server restarts.
  • Persistent Databases (e.g. SQLite, PostgreSQL): Stores checkpoints in relational tables. Required for production servers.

3. Implementing SQLite Checkpointing

To save checkpoints in a local SQLite file:

First, install the SQLite checkpointer driver package:

# Install the sqlite checkpointer plugin
npm install @langchain/langgraph-checkpoint-sqlite

Configure the SQLite saver in your graph setup:

// src/services/persistentGraph.ts
import { StateGraph, Annotation } from "@langchain/langgraph";
import { SqliteSaver } from "@langchain/langgraph-checkpoint-sqlite";

const StateAnnotation = Annotation.Root({
  ticketId: Annotation<string>(),
  status: Annotation<string>(),
});

const workflow = new StateGraph(StateAnnotation)
  // Register nodes and edges...
  .setEntryPoint("node1");

// 1. Initialize the SQLite database checkpointer
const sqliteSaver = SqliteSaver.fromConnString("./checkpoints.db");

// 2. Compile binding the saver
export const persistentApp = workflow.compile({
  checkpointer: sqliteSaver,
});

4. Querying History States

You can query the history of an execution thread by calling getStateHistory():

const historyList = [];
for await (const stateRecord of persistentApp.getStateHistory({ configurable: { thread_id: "order_99" } })) {
  historyList.push({
    checkpointId: stateRecord.config.configurable.checkpoint_id,
    values: stateRecord.values,
  });
}

console.log("Total checkpoints stored for thread:", historyList.length);
Published on Last updated: