Skip to main content
Persist every agent turn to external databases — conversations resume across restarts and you can query run history later.
The user continues a conversation; database hooks persist each turn so the session survives restarts.

Quick Start

1

Simple usage

2

With session continuity

3

CLI with persistence


How It Works

On first chat, the adapter loads prior messages for the session_id. Each turn writes user and agent messages automatically — no manual save calls.
SQLite persistence uses the hardened sqlite_connect connector by default, so it works on Docker Desktop, NFS, Fly.io network volumes, and Kubernetes PVCs without corruption risk.

Configuration Options

Pass a db() instance via memory= (or MemoryConfig(db=…, session_id=…) for explicit sessions). The three per-store dicts mirror PersistenceConfig and each routes to exactly one store factory.

Multi-backend configuration

Per-store option dicts send backend-specific kwargs to a single store, so mixing Postgres, Redis, and Qdrant never leaks an unrelated kwarg.
Each kwarg reaches exactly one factory:
Passing backend kwargs directly to db(**options) is deprecated — it emits a DeprecationWarning and broadcasts each key to every store, which crashes any factory that doesn’t accept it. Scope kwargs with the per-store dicts instead.

Environment variables

Database backends require the praisonai wrapper (pip install praisonai). The core SDK defines DbAdapter; implementations live in praisonai.db.

Default session ID

If you omit session_id, PraisonAI generates a fresh ID per instance (UTC hour + agent hash + random suffix):
The auto ID ends in a per-instance random suffix, so:
  • Two Agent(name="Assistant") instances never share history — no cross-instance bleed, even when started in the same UTC hour.
  • The auto ID cannot resume a conversation across process restarts — a new instance gets a new suffix, hence a new session. For resumable multi-turn conversations, pass an explicit session_id. See Session Persistence.

Custom DB Adapter

Any object with the right method shape works as a DB adapter — no base class, no import required.
The adapter persists each turn and returns prior messages on on_agent_start, so the session resumes across restarts.

Required vs optional methods

The two optional methods (PR #5082) let a resumed session hand the model the same tool transcript the JSON store already keeps.

Minimal adapter

Adapters that omit on_assistant_message / on_tool_message still work — assistant tool-call turns fall back to text-only via on_agent_message, and raw role="tool" turns are dropped. Add them to give resumed sessions the same tool transcript the JSON store already has.
Third-party code can feature-detect the capability with isinstance:
Reference: PraisonAI PR #5082 (fixes #5075).

Docker (local development)


CLI commands


Async-Safe Initialisation

The DatabaseAdapter’s async callbacks (on_agent_start, on_user_message, on_agent_message, on_tool_call, on_agent_end) never block the event loop. Store construction runs off-loop via asyncio.to_thread, so FastAPI handlers, Jupyter notebooks, and async test suites all work without stalls on cold startup.

Transient Failure Handling

When a database is temporarily unavailable (bad config, network blip, cloud auth glitch), the adapter records the failure and waits before re-attempting. This prevents hammering a down backend on every agent callback while still recovering automatically once the backend is back. The cool-down period is configurable via init_retry_cooldown (default 30 seconds):
After a soft init failure (raised during _ainit_stores()), the adapter pauses for init_retry_cooldown seconds before re-running store construction on the next callback. Persistence resumes automatically once the backend becomes reachable — no process restart needed.

Best Practices

The auto ID is a fresh, per-instance value — a new instance gets a new random suffix and starts a new session. Set MemoryConfig(session_id=…) for any resumable case where users return to the same thread across restarts.
Never hardcode database URLs — use os.getenv("PRAISON_CONVERSATION_URL").
praisonai persistence doctor validates connectivity for conversation, state, and knowledge stores.
Conversation history, run traces, and vectors scale differently — configure database_url, state_url, and knowledge_url independently.

Run History

Query persisted runs and traces

Session Persistence

JSON file sessions without a database