Multi-Tenant AI Agent Memory Patterns

Free · Open source (MIT) · Works with LangChain, CrewAI, AutoGen · No signup

Building SaaS AI agents that serve multiple customers? You need clean memory isolation between tenants. Without proper namespace separation, one customer's chat history bleeds into another's—a privacy nightmare and broken user experience. Here's how to implement rock-solid multi-tenant AI agent memory.

Why Multi-Tenant AI Memory Breaks

Most developers building SaaS AI products hit this wall: their agents work perfectly for single users, but fall apart with multiple tenants. The core issue is shared memory space.

Consider a customer support chatbot serving companies A and B. Without tenant isolation, the agent might remember Company A's confidential pricing when talking to Company B. Or worse—it retrieves the wrong conversation history entirely.

Traditional solutions like in-memory dictionaries or session caches don't persist across restarts. Database approaches require complex schema design and ORM overhead. Vector databases like Pinecone work for semantic search but overkill simple key-value agent memory.

The real pain hits during development: you're constantly debugging whose memory belongs to whom, why conversations cross-contaminate, and how to clean up orphaned data between test runs.

The Namespace Solution

Install BotWire Memory and use namespace isolation:

pip install botwire
from botwire import Memory

# Each tenant gets isolated memory
tenant_a_memory = Memory("tenant-a")
tenant_b_memory = Memory("tenant-b")

# Completely isolated operations
tenant_a_memory.set("user_preference", "dark_mode")
tenant_b_memory.set("user_preference", "light_mode")

# No cross-contamination
print(tenant_a_memory.get("user_preference"))  # "dark_mode"
print(tenant_b_memory.get("user_preference"))  # "light_mode"
print(tenant_a_memory.get("nonexistent"))      # None

This creates permanent memory isolation per namespace that survives process restarts and scales across machines.

Memory Patterns for SaaS AI

The namespace pattern handles complex multi-tenant scenarios. Here's a production-ready customer service agent:

from botwire import Memory
import uuid

class TenantAgent:
    def __init__(self, tenant_id, user_id=None):
        # Hierarchical namespacing
        if user_id:
            self.memory = Memory(f"tenant-{tenant_id}-user-{user_id}")
        else:
            self.memory = Memory(f"tenant-{tenant_id}")
    
    def remember_conversation(self, message, response):
        conversation_id = str(uuid.uuid4())
        self.memory.set(f"chat-{conversation_id}", {
            "message": message,
            "response": response,
            "timestamp": time.time()
        })
    
    def get_user_context(self):
        return self.memory.get("user_context") or {}

# Usage across different tenants
acme_agent = TenantAgent("acme-corp", "user-123")
globodyne_agent = TenantAgent("globodyne", "user-456")

acme_agent.memory.set("api_key", "acme-secret-key")
globodyne_agent.memory.set("api_key", "globodyne-different-key")

Each tenant's data remains completely isolated. You can list all keys in a namespace, implement TTL by checking timestamps, and clean up entire tenant namespaces when customers churn.

Cross-process access works automatically—your worker processes, web servers, and background jobs all share the same persistent memory without coordination code.

Framework Integration

BotWire integrates directly with existing AI frameworks through specialized adapters:

# LangChain chat history per user
from botwire import BotWireChatHistory
from langchain.memory import ConversationBufferMemory

def create_tenant_chain(tenant_id, user_id):
    chat_history = BotWireChatHistory(session_id=f"{tenant_id}-{user_id}")
    memory = ConversationBufferMemory(chat_memory=chat_history)
    return LLMChain(llm=your_llm, memory=memory)

# CrewAI with tenant-specific memory tools
from botwire.memory import memory_tools

def create_crew_for_tenant(tenant_id):
    tools = memory_tools(f"crew-{tenant_id}")  # remember, recall, list_memory
    agent = Agent(
        role="Customer Support",
        tools=tools,
        goal="Help customers using persistent memory"
    )
    return Crew(agents=[agent])

When NOT to Use BotWire

BotWire Memory isn't the right tool for:

Vector/semantic search — Use Pinecone, Weaviate, or pgvector for embedding-based retrieval • High-throughput applications — 1000 writes/day per namespace fits most SaaS use cases, not high-frequency trading • Sub-millisecond latency — HTTP API adds ~50-200ms; use Redis for ultra-low latency caching

FAQ

Why not just use Redis? Redis requires infrastructure setup, auth management, and doesn't namespace cleanly. BotWire works immediately with zero configuration and built-in tenant isolation.

Is this actually free? Yes, 1000 writes/day per namespace forever. Most SaaS apps use 10-100 writes per user per day. Unlimited reads mean you can query freely.

What about data privacy? Self-host the open-source version (MIT license) for full control, or use the hosted version which doesn't require signup—your namespace is your identifier.

Get Started

Multi-tenant AI memory isolation shouldn't be complicated. BotWire Memory gives you namespace-based tenant separation that just works.

pip install botwire

Start building at https://botwire.dev — no signup required, free tier forever.

Install in one command:

pip install botwire

Start free at botwire.dev