> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Persistence Backend Plugins

> Add custom conversation, knowledge, and state stores via Python entry points

Register custom storage backends for conversations, knowledge, and state through a central registry.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent, db

agent = Agent(
    name="Assistant",
    instructions="Persist conversations to MySQL",
    db=db(database_url="mysql://user:pass@localhost:3306/praisonai"),
    session_id="session-1",
)
agent.start("Hello — save this conversation")
```

The user chats with the agent; registered plugins persist conversations, knowledge, and state.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Agent[🤖 Agent] --> Registry[📝 StoreRegistry]
    Registry --> Conv[💬 Conversation]
    Registry --> Know[📚 Knowledge]
    Registry --> State[🔄 State]
    Plugin[📦 Entry Point] --> Registry

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef registry fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef store fill:#10B981,stroke:#7C90A0,color:#fff
    classDef plugin fill:#F59E0B,stroke:#7C90A0,color:#fff

    class Agent agent
    class Registry registry
    class Conv,Know,State store
    class Plugin plugin
```

## Quick Start

<Steps>
  <Step title="Simple Usage">
    Use a built-in backend via the registry:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.persistence import create_conversation_store

    store = create_conversation_store(
        "mysql",
        url="mysql://user:pass@localhost:3306/praisonai",
    )
    ```
  </Step>

  <Step title="With Configuration">
    Register a custom backend at runtime:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.persistence import get_default_registry

    def my_store_factory(url=None, **kwargs):
        from my_pkg import MyConversationStore
        return MyConversationStore(url=url, **kwargs)

    registry = get_default_registry("conversation")
    registry.register("mybackend", my_store_factory, aliases=("mb",))
    store = registry.create("mb", url="proto://host")
    ```

    <Note>
      `CONVERSATION_STORES`, `KNOWLEDGE_STORES`, and `STATE_STORES` are still importable from `praisonai.persistence.registry` for backward compatibility — they are now **lazy attributes** that build on first access via `__getattr__`. New code should prefer `get_default_registry(kind)` for clarity.
    </Note>

    Package it as an entry point in `pyproject.toml`:

    ```toml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    [project.entry-points."praisonai.conversation_stores"]
    mybackend = "my_pkg.factory:create_store"
    ```
  </Step>
</Steps>

***

## How It Works

<Note>
  **No import-time cost.** Importing `praisonai.persistence.registry` no longer walks Python entry points or registers the \~40 built-in loaders as a side effect — each kind's registry is built lazily the first time you call `get_default_registry(kind)` (or reference the legacy `*_STORES` names). `import praisonai` is now safe to run in tests, notebooks, and multi-tenant runtimes without side effects.
</Note>

Three global registries cover each storage kind:

| Registry              | Entry-point group               | Purpose                     |
| --------------------- | ------------------------------- | --------------------------- |
| `CONVERSATION_STORES` | `praisonai.conversation_stores` | Chat history and sessions   |
| `KNOWLEDGE_STORES`    | `praisonai.knowledge_stores`    | Vector databases and RAG    |
| `STATE_STORES`        | `praisonai.state_stores`        | Application state and cache |

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant App
    participant Registry as StoreRegistry
    participant Factory
    participant Store

    App->>Registry: create("backend", **kwargs)
    Registry->>Factory: resolve alias → factory
    Factory->>Store: instantiate
    Store-->>App: store instance
```

***

## Multi-tenant isolation

All three factory functions accept an injected `registry=` — pass your own `StoreRegistry` to keep tenant registrations from leaking into the process-default registry.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.persistence import StoreRegistry, create_conversation_store

def tenant_a_factory(url=None, **kwargs):
    from my_pkg import MyConversationStore
    return MyConversationStore(url=url, **kwargs)

tenant_a = StoreRegistry("conversation", "praisonai.conversation_stores")
tenant_a.register("mystore", tenant_a_factory)

store = create_conversation_store(
    "mystore",
    url="proto://host",
    registry=tenant_a,   # scoped — does not touch the process default
)
```

Same shape for `create_knowledge_store(..., registry=)` and `create_state_store(..., registry=)`. See [Registry Dependency Injection](/docs/features/registry-dependency-injection) for the wider pattern.

***

## Configuration Options

### StoreRegistry API

<Info>
  Third-party backend authors register plugins via the same three entry-point groups (`praisonai.conversation_stores` / `praisonai.knowledge_stores` / `praisonai.state_stores`). Lazy loading means the entry-point scan runs on **first use of that kind** only, not on every `import praisonai`.
</Info>

| Method                 | Signature                                          | Description                                                                                                                                                      |
| ---------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `register`             | `register(name, factory, *, aliases=())`           | Register a backend factory with optional aliases                                                                                                                 |
| `create`               | `create(name, **kwargs)`                           | Create a store instance by name or alias                                                                                                                         |
| `list_registered`      | `() -> list[str]`                                  | All registered backend names                                                                                                                                     |
| `list_aliases`         | `() -> dict[str, str]`                             | Alias → canonical name mappings                                                                                                                                  |
| `get_default_registry` | `get_default_registry(kind: str) -> StoreRegistry` | Return the process-default registry for `"conversation"` / `"knowledge"` / `"state"`, building it lazily on first call. Prefer DI (`registry=`) in library code. |

### Built-in conversation backends

`postgres`, `async_postgres`, `mysql`, `async_mysql`, `sqlite`, `sync_sqlite`, `async_sqlite`, `json`, `singlestore`, `supabase`, `surrealdb`, `turso`

Common aliases: `neon`, `cockroachdb`, `crdb` → `postgres`; `aiomysql` → `async_mysql`; `libsql` → `turso`.

### Built-in knowledge backends

`chroma`, `qdrant`, `pinecone`, `weaviate`, `lancedb`, `milvus`, `pgvector`, `redis`, `cassandra`, `clickhouse`, and others.

### Built-in state backends

`redis`, `dynamodb`, `firestore`, `mongodb`, `async_mongodb`, `upstash`, `memory`, `gcs`

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use lazy imports in factories">
    Follow built-in backends — import heavy dependencies inside the factory function, not at module level.
  </Accordion>

  <Accordion title="Provide meaningful aliases">
    Register short aliases (`mb`, `pg`) alongside canonical names for easier CLI and config usage.
  </Accordion>

  <Accordion title="Handle unknown backends clearly">
    Factory functions should raise clear errors with connection hints — the registry lists available backends on `ValueError`.
  </Accordion>

  <Accordion title="Keep factories thread-safe">
    Registries use `threading.Lock` — factory functions should also be safe for concurrent creation.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Database Persistence" icon="database" href="/docs/features/persistence">
    Overview of all persistence backends
  </Card>

  <Card title="Framework Adapter Plugins" icon="plug" href="/docs/features/framework-adapter-plugins">
    Plugin system for multi-agent frameworks
  </Card>
</CardGroup>
