Skip to main content
PraisonAI’s memory backends are pluggable — register your own adapter to store agent memory in any system. The user chats with the agent; your custom memory adapter persists and retrieves facts from your chosen backend.

Quick Start

1

Simple Usage

Use a built-in adapter via string to anchor the mental model:
2

With a Custom Adapter

Register your adapter, then point the agent at it:

The Adapter Is the Single Source of Truth

As of PR #3515, a configured adapter handles store, search, reset, and delete for every provider — not just sqlite / in_memory. Data written through a registered adapter (e.g. dakera) is now findable, resettable, and deletable through that same adapter. No sqlite fallback or dual-write pattern is needed.
Previously, search, reset, and delete only delegated to the adapter when the provider was hardcoded sqlite or in_memory. Any other registered adapter stored data correctly but reads hit the empty legacy tables and returned [] — memory was effectively write-only. All four operation paths now gate symmetrically on whether an adapter is configured. Round-trip through a custom adapter — store then find:
Memory-storage failures now surface as explicit errors when an adapter is configured. A failed long-term store raises RuntimeError instead of silently dropping the write to a schema-incompatible legacy table. Wrap agent.start() when using a custom adapter that may reject writes.

How It Works

When Memory initialises, it resolves the provider through the adapter registry — the only code path for backend setup since PR #2060 removed orphaned legacy _init_* methods.

Every operation routes through the adapter

Once you register an adapter (e.g. add_memory_adapter("dakera", DakeraAdapter)) and set provider="dakera" — or pass the adapter directly — every read and every write routes through it: store_*, search_*, reset_*, and delete_*. There is no provider in {sqlite, in_memory} gate. Before this became symmetric, a registered adapter’s writes went to its own table while every search_* looked at the legacy long_mem table the adapter never created — so searches returned [] and resets/deletes no-op’d. Store, search, reset, and delete now share one source of truth. The dedicated chroma / mem0 / mongodb write paths still take priority for those providers.
An adapter that implements store_long_term must implement search_long_term (and, for reset/delete to work, reset_short_term / reset_long_term / delete_memory(memory_id, tier=...)). If a store succeeds but the adapter store fails, store_long_term now raises RuntimeError("Long-term store failed via memory adapter; the legacy long_mem table is not schema-compatible.") — a surfaced failure rather than the previous silent drop.

Built-in Adapters

Heavy backends register as factories in praisonaiagents.memory.adapters.factories so optional dependencies load only when requested. Adapter operations (as of PR #3515): store ✅ · search ✅ · reset ✅ · delete ✅ — every operation routes through the configured adapter, for any provider, not just sqlite / in_memory.

Register Your Own Adapter

Implement MemoryProtocol — at minimum: store_short_term, search_short_term, store_long_term, search_long_term, and get_all_memories.
add_memory_adapter and register_memory_adapter are synonyms; both work. add_memory_adapter is the canonical name per the SDK naming convention (add_X = register something).
Then use it from an agent:

Registry API at a Glance

Common Patterns

Async adapter — implement AsyncMemoryProtocol (astore_short_term, asearch_short_term, etc.) when your backend is async-native. Lazy-loaded heavy backend — use add_memory_factory(name, create_fn) (or its synonym register_memory_factory) so imports like chromadb or pymongo happen inside the factory, not at package import time. Extending an existing adapter — subclass SqliteMemoryAdapter or wrap InMemoryAdapter and register under a new name. Inspect the registry — check what’s registered before wiring an agent:

Best Practices

Register adapters with add_memory_adapter or add_memory_factory instead of monkey-patching Memory internals.
Sync methods satisfy MemoryProtocol; add AsyncMemoryProtocol methods if your store supports non-blocking I/O.
Implement close() on adapters that hold clients (MongoDB, ChromaDB). Session.close() calls memory.close_connections() which forwards to the adapter.

Memory Concepts

Provider strings, short-term vs long-term, and configuration basics.

Memory Cleanup

Session teardown and adapter close() lifecycle.

MongoDB Memory

Atlas Vector Search and use_vector_search configuration.

Dakera Memory

Self-hosted, decay-weighted vector recall via the Dakera server.

Memory Troubleshooting

ImportError and fallback behaviour when providers are missing.