Artificial Intelligence Blogs Posts
cancel
Showing results for 
Search instead for 
Did you mean: 

Introduction

LangGraph is becoming a popular framework for building AI agents that need to maintain state across interactions. If you're running these agents on SAP BTP with HANA Cloud as your database, you'll quickly find that LangGraph's built-in persistence options don't include HANA. This post introduces langgraph-checkpoint-hana, an open-source package I built to fill that gap. It implements the full LangGraph checkpointer interface for HANA Cloud, so your agent state lives in the same database as your business data.

What's a checkpointer

LangGraph is a framework for building stateful AI agents. A checkpointer saves the agent's state at each step of execution. This enables:

  • Persistent memory across sessions (the agent remembers previous interactions)
  • Fault recovery (if the process crashes, it resumes from the last saved state instead of starting over)
  • Time travel (you can inspect or roll back to any previous state)

LangGraph ships with checkpointers for PostgreSQL, SQLite, and InMemory. The community has built others for Redis, DynamoDB, Snowflake. None for HANA.

Why HANA

If you're already using HANA Vector Store for RAG (via langchain-hanadb), adding a separate database just for checkpointing adds unnecessary complexity. Vectors and agent state in the same database, same instance, same credentials.

On BTP specifically, HANA Cloud is already there. Your Kyma or CF app already has a HANA binding. Using it for checkpointing means no additional service instances.

Installation

pip install langgraph-checkpoint-hana

Requires hdbcli (installed automatically) and Python 3.10+.

Usage

Three ways to create the checkpointer:

From connection parameters

from langgraph_checkpoint_hana import HANASaver

with HANASaver.from_conn_info(
    address="your-instance.hanacloud.ondemand.com",
    port=443,
    user="DBADMIN",
    password="your-password",
) as checkpointer:
    graph = workflow.compile(checkpointer=checkpointer)
    result = graph.invoke(inputs, {"configurable": {"thread_id": "t1"}})

From environment variables

Useful in containers on Kyma/CF where credentials come from service bindings:

import os
os.environ["HANA_HOST"] = "your-instance.hanacloud.ondemand.com"
os.environ["HANA_PORT"] = "443"
os.environ["HANA_USER"] = "DBADMIN"
os.environ["HANA_PASSWORD"] = "your-password"

from langgraph_checkpoint_hana import HANASaver
checkpointer = HANASaver.from_env()
checkpointer.setup()

From an existing hdbcli connection

If your application already manages its own HANA connections:

from hdbcli import dbapi
from langgraph_checkpoint_hana import HANASaver

conn = dbapi.connect(address="...", port=443, user="...", password="...")
checkpointer = HANASaver(conn=conn)
checkpointer.setup()

What it creates

Calling setup() creates two tables if they don't exist:

  • LANGGRAPH_CHECKPOINTS -- stores graph state snapshots
  • LANGGRAPH_CHECKPOINT_WRITES -- stores pending writes for fault recovery

Both keyed by (thread_id, checkpoint_ns, checkpoint_id). Uses NCLOB columns for serialized data. Table existence is checked via SYS.TABLES, not try/except.

Full example with a LangGraph agent

from langgraph_checkpoint_hana import HANASaver
from langgraph.graph import StateGraph, MessagesState, START, END

def chatbot(state: MessagesState) -> MessagesState:
    # your LLM call here
    return {"messages": [response]}

with HANASaver.from_env() as checkpointer:
    workflow = StateGraph(MessagesState)
    workflow.add_node("chatbot", chatbot)
    workflow.add_edge(START, "chatbot")
    workflow.add_edge("chatbot", END)

    graph = workflow.compile(checkpointer=checkpointer)

    config = {"configurable": {"thread_id": "session-42"}}

    # First interaction
    graph.invoke({"messages": [("human", "What's our AP aging?")]}, config)

    # Second interaction - agent remembers the first one
    graph.invoke({"messages": [("human", "Break it down by vendor")]}, config)

    # Check state
    state = graph.get_state(config)

Thread cleanup

# Delete all state for a thread
checkpointer.delete_thread("session-42")

Useful for GDPR compliance, cleaning up test data, or recovering from corrupted state (orphaned tool calls that cause downstream errors -- if you've hit this in production you know what I mean).

Technical notes

  • Writes use HANA's UPSERT ... WITH PRIMARY KEY for atomic insert-or-update
  • Serialization uses LangGraph's JsonPlusSerializer (same as the official checkpointers)
  • Async methods delegate to sync because hdbcli is a synchronous C-extension driver. For high-concurrency async deployments, wrap with asyncio.to_thread()
  • Tested with LangGraph 0.2.x/0.3.x, HANA Cloud 2024.x/2025.x, Python 3.10-3.12

Conclusion

If you're building LangGraph agents on BTP, this package lets you keep agent state in the same HANA Cloud instance where your business data already lives. No extra databases, no extra infrastructure. Install it with pip install langgraph-checkpoint-hana and try it out.

The package is MIT licensed and I welcome contributions. If you run into issues or have suggestions, open an issue on the GitHub repo.

1 Comment
Labels in this area