Files
langgraphjs/libs/checkpoint-redis
John Kennedy 8fb6376a75 chore: update Vitest to 4.1.9 (#2587)
## Summary
- update all workspace `vitest` declarations to `4.1.9`
- update `@vitest/browser-playwright` and `@vitest/browser-webdriverio`
declarations to `4.1.9`
- refresh `pnpm-lock.yaml` so no `vitest`/`@vitest/browser` versions
below `4.1.9` remain

## Validation
- `sfw pnpm install`
- `pnpm format:check`
- `pnpm lint`
- `pnpm build`
- targeted audit check: no `vitest` or `@vitest/browser` advisories
remain
- `pnpm --filter create-langgraph test`
- `pnpm --filter @langchain/react test`
- `pnpm --filter @langchain/svelte test`
- `pnpm --filter @langchain/vue test`
- `pnpm --filter @langchain/angular test`
- `pnpm --filter @langchain/langgraph test`

## Notes
- `pnpm --filter @langchain/langgraph test:browser` did not run locally
because Playwright Chromium for the updated provider was not installed
on this machine; Vitest exited before running tests with Playwright's
`pnpm exec playwright install` message.
- The SDK Vitest suites passed but printed Vitest's post-success
close-timeout warning.

Co-authored-by: John Kennedy <jkennedyvz@users.noreply.github.com>
2026-07-03 23:18:35 -07:00
..
2026-06-17 15:34:21 -07:00
2025-10-17 16:34:43 -07:00

@langchain/langgraph-checkpoint-redis

Redis checkpoint and store implementation for LangGraph.

Overview

This package provides Redis-based implementations for:

  1. Checkpoint Savers: Store and manage LangGraph checkpoints using Redis
    • RedisSaver: Standard checkpoint saver that maintains full checkpoint history
    • ShallowRedisSaver: Memory-optimized saver that only keeps the latest checkpoint per thread
  2. RedisStore: Redis-backed key-value store with optional vector search capabilities

Installation

npm install @langchain/langgraph-checkpoint-redis

Dependencies

Redis Requirements

This library requires Redis with the following modules:

  • RedisJSON - For storing and manipulating JSON data
  • RediSearch - For search and indexing capabilities

Redis 8.0+

If you're using Redis 8.0 or higher, both RedisJSON and RediSearch modules are included by default.

Redis < 8.0

For Redis versions lower than 8.0, you'll need to:

  • Use Redis Stack, which bundles Redis with these modules
  • Or install the modules separately in your Redis instance

Usage

Standard Checkpoint Saver

import { RedisSaver } from "@langchain/langgraph-checkpoint-redis";

const checkpointer = await RedisSaver.fromUrl(
    "redis://localhost:6379",
    {
        defaultTTL: 60, // TTL in minutes
        refreshOnRead: true
    }
);

// Indices are automatically created by fromUrl()

// Use with your graph
const config = {configurable: {thread_id: "1"}};

// Metadata must include required fields
const metadata = {
    source: "update",  // "update" | "input" | "loop" | "fork"
    step: 0,
    parents: {}
};

await checkpointer.put(config, checkpoint, metadata, {});
const loaded = await checkpointer.get(config);

Shallow Checkpoint Saver

The ShallowRedisSaver is a memory-optimized variant that only keeps the latest checkpoint per thread:

import { ShallowRedisSaver } from "@langchain/langgraph-checkpoint-redis/shallow";

// Create a shallow saver that only keeps the latest checkpoint
const shallowSaver = await ShallowRedisSaver.fromUrl("redis://localhost:6379");

// Use it the same way as RedisSaver
const config = {
    configurable: {
        thread_id: "my-thread",
        checkpoint_ns: "my-namespace"
    }
};

const metadata = {
    source: "update",
    step: 0,
    parents: {}
};

await shallowSaver.put(config, checkpoint, metadata, versions);

// Only the latest checkpoint is kept - older ones are automatically cleaned up
const latest = await shallowSaver.getTuple(config);

Key differences from RedisSaver:

  • Storage: Only keeps the latest checkpoint per thread (no history)
  • Performance: Reduced storage usage and faster operations
  • Inline storage: Channel values are stored inline (no separate blob storage)
  • Automatic cleanup: Old checkpoints and writes are automatically removed

RedisStore

The RedisStore provides a key-value store with optional vector search capabilities:

import { RedisStore } from "@langchain/langgraph-checkpoint-redis/store";

// Basic key-value store
const store = await RedisStore.fromConnString("redis://localhost:6379");

// Store with vector search
const vectorStore = await RedisStore.fromConnString("redis://localhost:6379", {
    index: {
        dims: 1536,  // Embedding dimensions
        embed: embeddings,  // Your embeddings instance
        distanceType: "cosine",  // or "l2", "ip"
        fields: ["text"],  // Fields to embed
    },
    ttl: {
        defaultTTL: 60,  // TTL in minutes
        refreshOnRead: true,
    }
});

// Put and get items
await store.put(["namespace", "nested"], "key1", {text: "Hello world"});
const item = await store.get(["namespace", "nested"], "key1");

// Search with namespace filtering
const results = await store.search(["namespace"], {
    filter: {category: "docs"},
    limit: 10,
});

// Vector search
const semanticResults = await vectorStore.search(["namespace"], {
    query: "semantic search query",
    filter: {type: "article"},
    limit: 5,
});

// Batch operations
const ops = [
    {type: "get", namespace: ["ns"], key: "key1"},
    {type: "put", namespace: ["ns"], key: "key2", value: {data: "value"}},
    {type: "search", namespacePrefix: ["ns"], limit: 10},
    {type: "list_namespaces", matchConditions: [{matchType: "prefix", path: ["ns"]}], limit: 10},
];
const results = await store.batch(ops);

TTL Support

Both checkpoint savers and stores support Time-To-Live (TTL) functionality:

const ttlConfig = {
    defaultTTL: 60,  // Default TTL in minutes
    refreshOnRead: true,  // Refresh TTL when items are read
};

const checkpointer = await RedisSaver.fromUrl("redis://localhost:6379", ttlConfig);

Edge & serverless runtimes (Cloudflare Workers, etc.)

The Redis savers and store use node-redis (createClient/createCluster), which opens a raw TCP/TLS socket via Node's net/tls modules. Some serverless/edge runtimes, most notably Cloudflare Workers, do not support raw outbound TCP connections, so connecting (and the initial index setup) will hang. This is the root cause for issues where the runtime reports that the Worker "had hung and would never generate a response".

This is a client/runtime limitation, not a persistence-flush problem. LangGraph awaits all pending checkpoint writes before invoke()/stream() resolves (see the base checkpoint package README), so as long as you await the run you do not need ctx.waitUntil() to keep the runtime alive for persistence.

Cloudflare Hyperdrive only supports Postgres/MySQL, so it cannot front Redis. To use Redis-backed persistence from Cloudflare Workers, use an HTTP-based Redis service such as Upstash Redis (@upstash/redis, which speaks REST and works in Workers) behind a small custom BaseCheckpointSaver implementation, rather than RedisSaver/ShallowRedisSaver.

Note: standard Node.js, Deno, and Bun deployments are unaffected — the Redis savers work there out of the box.

Development

Running Tests

# Run tests (uses TestContainers)
yarn test

# Run tests in watch mode
yarn test:watch

# Run integration tests
yarn test:int

License

MIT