Swap Agno’s in-memory database for a Synap-backed one. Agents that useDocumentation Index
Fetch the complete documentation index at: https://docs.maximem.ai/llms.txt
Use this file to discover all available pages before exploring further.
enable_user_memories=True keep working without code changes — they just gain a persistent, semantically searchable memory store.
Overview
This guide shows how to add Synap to an Agno application to build agents that:- Persist user memories across processes and deployments
- Retrieve memories semantically rather than by raw key lookup
- Serve many users from a single database instance, scoped per-call by
user_id
InMemoryDb that routes memory operations through Synap.
| Class | Agno interface | Purpose |
|---|---|---|
SynapDb | InMemoryDb subclass | Persistent user-memory store backed by Synap |
Setup
Install the package alongside Agno:.env
Basic integration
The smallest useful integration constructs aSynapDb, hands it to an Agent, and turns on enable_user_memories. Each agent.run(..., user_id=...) call now reads and writes against Synap rather than a process-local dict:
user_id is supplied per call — SynapDb is constructed once and serves all users in the process. The customer_id (organization scope) is fixed at construction. Memory reads degrade gracefully on Synap outages; writes raise so silent data loss is impossible.
Core concepts
SynapDb
SynapDb extends Agno’s InMemoryDb and overrides the four user-memory methods. Everything else (session state, non-memory storage) is inherited unchanged, so existing Agno code continues to work:
| Method | Behavior |
|---|---|
upsert_user_memory(user_id, memory) | Writes a new or updated memory to Synap |
get_user_memory(user_id, memory_id) | Fetches a specific memory by ID |
get_user_memories(user_id, query) | Retrieves the user’s memories via semantic search |
get_all_memory_topics(user_id) | Returns unique memory topics via a broad search |
Per-call user scoping
Agno passesuser_id as a runtime argument to every memory call rather than baking it into the database. That means one SynapDb instance can serve any number of users:
user_id scope, so memories never leak between users — even though the database object is shared.
Complete example: long-lived agent serving many users
The pattern below is what most production Agno deployments end up with: oneSynapDb and one Agent at module load, and a thin handler that supplies user_id per request:
- One
SynapDb, many users. The database is constructed once;user_idis the per-call scope. - The
customer_idis the tenant boundary. All users sharing aSynapDbinstance are inside the samecustomer_id— for cross-tenant services, build a separateSynapDbper tenant. - Agno’s behavior is unchanged.
enable_user_memories,description, and run signatures all work exactly as in vanilla Agno; you’ve only swapped the storage layer.
Advanced patterns
Multi-tenant scoping
SynapDb takes the customer-tenant scope at construction (customer_id) and the user scope per call (user_id). customer_id is required on B2B Synap instances and ignored on single-tenant ones. See Memory Scopes.
SynapDb rather than mixing tenants on one instance.
Memory topic discovery
get_all_memory_topics is implemented as a broad Synap search and returns unique topics across the user’s memory pool. Useful for building UIs that let a user browse what’s been remembered about them, or for prompt enrichment (“Here are the topics we’ve discussed: …”).
Failure semantics
The integration follows the Synap-wide contract:get_user_memory/get_user_memoriesdegrade gracefully — return empty results and log an error if Synap is unreachable.upsert_user_memorysurfaces failures — raisesSynapIntegrationErrorso the agent and caller know persistence failed.
Next steps
Google ADK
FunctionTool factory for Google ADK agents.OpenAI Agents
Function tools for the OpenAI Agents SDK.
Memory Scopes
How
user_id and customer_id interact across reads and writes.Ingestion
Direct ingestion API for pipelines that need finer control than
upsert_user_memory.