A PostgreSQL-based checkpointer for LangGraph that enables persistent storage and retrieval of graph execution checkpoints. This package allows you to maintain state across sessions in your LangGraph applications.
- π Persistent Checkpoints: Save and restore LangGraph execution states to PostgreSQL
- π Thread Management: Organize checkpoints by thread IDs for multi-conversation support
- π History Traversal: Navigate through checkpoint history with parent-child relationships
- β‘ Automatic Setup: Database tables are created automatically on first use
- π§ Flexible Configuration: Support for environment variables and connection strings
npm i langgraph-postgres-checkpointer
or with yarn:
yarn add langgraph-postgres-checkpointer
- Node.js >= 16.0.0
- PostgreSQL database
@langchain/langgraph
>= 0.0.33
Create a .env
file or set these environment variables:
DB_USERNAME=your_username
DB_PASSWORD=your_password
DB_HOST=localhost
DB_PORT=5432
DB_NAME=your_database
import { PostgresSaver, getPostgresConfig } from '@your-scope/langgraph-postgres-checkpointer';
// Using environment variables
const checkpointer = await PostgresSaver.fromConnString(getPostgresConfig());
// Or using a custom configuration
const checkpointer = await PostgresSaver.fromConnString({
user: 'username',
password: 'password',
host: 'localhost',
port: 5432,
database: 'mydb'
});
// Or using a connection string
const checkpointer = await PostgresSaver.fromConnString({
connectionString: 'postgresql://username:password@localhost:5432/mydb'
});
import { StateGraph } from '@langchain/langgraph';
// Define your graph state
const graph = new StateGraph({
// your graph configuration
});
// Compile with checkpointer
const app = graph.compile({
checkpointer: checkpointer
});
// Run with thread ID for persistence
const config = {
configurable: {
thread_id: "conversation-123"
}
};
const result = await app.invoke(input, config);
The main class for checkpoint persistence.
Creates a new PostgresSaver instance with the provided database configuration.
Retrieves a specific checkpoint or the latest checkpoint for a thread.
list(config: RunnableConfig, limit?: number, before?: RunnableConfig): AsyncGenerator<CheckpointTuple>
Lists checkpoints for a specific thread with optional pagination.
put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>
Saves a new checkpoint or updates an existing one.
Generates PostgreSQL configuration from environment variables.
Supported environment variables:
DB_USERNAME
orPGUSER
- Database usernameDB_PASSWORD
orPGPASSWORD
- Database passwordDB_HOST
orPGHOST
- Database host (default: 'localhost')DB_PORT
orPGPORT
- Database port (default: 5432)DB_NAME
orPGDATABASE
- Database name
The checkpointer automatically creates the following table:
CREATE TABLE IF NOT EXISTS checkpoints (
thread_id TEXT NOT NULL,
checkpoint_id TEXT NOT NULL,
parent_id TEXT,
checkpoint TEXT,
metadata TEXT,
PRIMARY KEY (thread_id, checkpoint_id)
);
You can provide a custom serializer when creating the checkpointer:
import { SerializerProtocol } from '@langchain/langgraph/dist/serde/base';
const customSerializer: SerializerProtocol<unknown> = {
stringify: (obj) => JSON.stringify(obj),
parse: (str) => JSON.parse(str)
};
const client = new Client(config);
await client.connect();
const checkpointer = new PostgresSaver(client, customSerializer);
// Each conversation gets its own thread ID
const thread1Config = { configurable: { thread_id: "user-123-chat-1" } };
const thread2Config = { configurable: { thread_id: "user-123-chat-2" } };
// Run separate conversations
await app.invoke(input1, thread1Config);
await app.invoke(input2, thread2Config);
// List checkpoints for a specific thread
const checkpoints = checkpointer.list(thread1Config, 10);
for await (const checkpoint of checkpoints) {
console.log(checkpoint.checkpoint_id);
}
The checkpointer includes built-in error handling with console logging. In production, you may want to implement custom error handling:
try {
const checkpointer = await PostgresSaver.fromConnString(config);
} catch (error) {
console.error('Failed to initialize checkpointer:', error);
// Handle error appropriately
}
Contributions are welcome! Please feel free to submit a Pull Request.
MIT
For issues and questions, please open an issue on Gi