Skip to main content

Production-ready PostgreSQL memory for LangGraph agents. Pool setup, checkpointer lifecycle, and common ops in one class.

Project description

LangGraph Postgres Memory

Production-ready PostgreSQL short-term memory for LangGraph agents. Pool setup, checkpointer lifecycle, and common operations in one class.

Note: This is a wrapper around langgraph-checkpoint-postgres — it does not reimplement checkpointing. It handles the boilerplate you'd otherwise copy-paste into every agent.

Features

  • One-line setup — connection pool, checkpointer, and lifecycle managed via async context manager
  • Production pool defaults — TCP keepalives, configurable idle/lifetime/timeout, schema isolation
  • Retry with backoff — transient Postgres errors retried automatically via tenacity
  • Thread cleanup — single CTE deletes across all 3 checkpoint tables in one round-trip
  • Bulk cleanup — delete threads older than N days using UUID v6 timestamp comparison
  • Health primitivesping() and pool_stats() for application health endpoints
  • Pydantic config — validated settings, pass however you load them (YAML, env vars, hardcoded)

Installation

# pip
pip install langgraph-postgres-memory

# uv
uv add langgraph-postgres-memory

Requirements

  • Python >= 3.11
  • PostgreSQL (tested with 16)

Usage

from langchain_core.messages import HumanMessage
from langgraph.graph import END, START, MessagesState, StateGraph
from langgraph_postgres_memory import PostgresMemoryConfig, PostgresShortTerm

# Define your graph
builder = StateGraph(MessagesState)
builder.add_node("echo", lambda state: {"messages": state["messages"]})
builder.add_edge(START, "echo")
builder.add_edge("echo", END)

# Configure memory
config = PostgresMemoryConfig(
    user="myuser",
    password="mypass",
    host="localhost",
    database="mydb",
    schema_name="agent_schema",  # default: "public"
)

async with PostgresShortTerm(config) as memory:
    # Compile your graph with the checkpointer
    graph = builder.compile(checkpointer=memory.checkpointer)

    # Invoke as usual
    result = await graph.ainvoke(
        {"messages": [HumanMessage(content="hello")]},
        {"configurable": {"thread_id": "thread-123"}},
    )

    # Read messages back
    messages = await memory.get_messages("thread-123")

    # Delete a thread
    await memory.delete_thread("thread-123")

    # Bulk cleanup
    await memory.delete_threads_older_than(days=30)

    # Health check
    alive = await memory.ping()
    stats = memory.pool_stats()

Without this library

# ~40 lines you copy-paste into every agent
conn_str = f"postgresql://{user}:{quote_plus(password)}@{host}:{port}/{db}"
conn_str += "?keepalives=1&keepalives_idle=30&..."
pool = AsyncConnectionPool(
    conninfo=conn_str, min_size=2, max_size=10,
    kwargs={"autocommit": True, "row_factory": dict_row},
    configure=..., check=...,
)
await pool.open()
checkpointer = AsyncPostgresSaver(pool)
await checkpointer.setup()
# ... try/finally to close pool
# ... raw SQL to delete threads across 3 tables
# ... dig into checkpoint JSONB to extract messages

Configuration

All pool and retry settings have sensible defaults. Override what you need:

config = PostgresMemoryConfig(
    user="myuser",
    password="mypass",
    database="mydb",

    # Pool tuning (defaults shown)
    pool_min_size=2,
    pool_max_size=20,
    pool_max_idle=300,       # seconds — tune down to ~30 for serverless (Neon, Supabase)
    pool_max_lifetime=1800,  # seconds — tune down to ~180 for serverless
    pool_timeout=30,         # seconds — acquisition timeout

    # Retry tuning
    retry_max_attempts=3,
    retry_max_wait=10,       # backoff cap in seconds
)

API Reference

Method Description
PostgresShortTerm(config) Constructor, takes PostgresMemoryConfig
async with PostgresShortTerm(config) Opens pool, initializes checkpointer, closes on exit
.checkpointer AsyncPostgresSaver instance for builder.compile(checkpointer=...)
await .get_messages(thread_id) Get messages from latest checkpoint
await .delete_thread(thread_id) Delete all checkpoints, blobs, and writes for a thread
await .delete_threads_older_than(days) Bulk delete threads older than N days
await .ping() Returns True if database is reachable
.pool_stats() Pool size, available connections, waiting requests

Testing

# Unit tests only (no database needed)
make test-unit

# Full test suite (starts Postgres via Docker, runs all tests, stops Postgres)
make test-all

# Or manually
docker compose -f tests/docker-compose.yml up -d --wait
uv run pytest --run-integration -v
docker compose -f tests/docker-compose.yml down

Acknowledgments

This project wraps langgraph-checkpoint-postgres from the LangChain team. The checkpointing engine, serialization, and schema management are entirely theirs — this library handles pool lifecycle, retry, and convenience operations on top.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

langgraph_postgres_memory-0.1.0.tar.gz (97.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

langgraph_postgres_memory-0.1.0-py3-none-any.whl (8.9 kB view details)

Uploaded Python 3

File details

Details for the file langgraph_postgres_memory-0.1.0.tar.gz.

File metadata

  • Download URL: langgraph_postgres_memory-0.1.0.tar.gz
  • Upload date:
  • Size: 97.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for langgraph_postgres_memory-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ce7e766694b5719a5e30ea228b8b7a534d66f43e93cd58297f511a3f914828f0
MD5 57233645c0c696d10750b45a1eb5d9db
BLAKE2b-256 5d471b11e2cc729bb8eec1853531dc2e7391a3f0b2ddf2306e87e7c4c53b5891

See more details on using hashes here.

File details

Details for the file langgraph_postgres_memory-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: langgraph_postgres_memory-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for langgraph_postgres_memory-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f9ddcc7e0db473e9b8f0b8c6d020662a278aeb4487648dc4377b58ce314f7d01
MD5 36fca9785e7fd40aa8139b98760d07a0
BLAKE2b-256 55a997235eb01780fd30d519e7145358ea26b6a2abbf77057abac74123b73a96

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page