DEV Community

Cover image for How the Pool Pattern Works in Multi-tenant RAG

How the Pool Pattern Works in Multi-tenant RAG

The pool pattern is a shared infrastructure approach where all tenants use the same Amazon Bedrock Knowledge Base, S3 bucket, and vector database. Here's how it works based on the implementation:

Core Concept

Instead of creating separate resources for each tenant, everyone shares:

  • One S3 bucket for all documents
  • One Knowledge Base for processing
  • One vector database (Pinecone, or AWS OpenSearch as an alternative) for storing embeddings
  • Metadata filtering to keep data separated

Step-by-Step Process

1. Document Upload with Tenant Metadata

When a user uploads a document, the system creates two files in S3:

// Original document
s3Key = `users/${userId}/agents/${agentId}/documents/${documentId}/${filename}`

// Metadata file (CRITICAL for tenant isolation)
metadataKey = `${document.s3Key}.metadata.json`
Enter fullscreen mode Exit fullscreen mode

The metadata file contains:

{
  "metadataAttributes": {
    "userId": "user123",
    "username": "john_doe",
    "agentId": "agent456",
    "filename": "report.pdf",
    "uploadDate": "2025-01-15T10:30:00Z"
  }
}
Enter fullscreen mode Exit fullscreen mode

This metadata is what enables tenant isolation in the shared system.

2. Shared Knowledge Base Processing

All documents go through the same Knowledge Base:

// Single shared Knowledge Base for all tenants
await this.bedrockClient.send(new StartIngestionJobCommand({
  knowledgeBaseId: this.configService.get('SHARED_KNOWLEDGE_BASE_ID'),
  dataSourceId: this.configService.get('SHARED_DATA_SOURCE_ID'),
}));
Enter fullscreen mode Exit fullscreen mode

The Knowledge Base:

  • Chunks all documents the same way
  • Uses the same embedding model
  • Stores vectors with the metadata in Pinecone

3. Querying with Tenant Isolation

When a user asks a question, the system filters results by their tenant ID:

filter: {
  andAll: [
    {
      equals: {
        key: 'userId',
        value: userId,  // Only this user's documents
      },
    },
    {
      equals: {
        key: 'agentId',
        value: agentId,  // Only this specific agent's documents
      },
    },
  ],
}
Enter fullscreen mode Exit fullscreen mode

This ensures User A never sees User B's documents, even though they're in the same database.

Visual Flow

  1. User uploads document → Creates S3 object + metadata.json
  2. Knowledge Base ingests → Processes both files together
  3. Vectors stored in Pinecone → With userId and agentId metadata
  4. User queries → Filter applied → Only their documents returned

Key Implementation Details

Agent Creation

Each user can have multiple agents (like different assistants):

async createAgent(userId: string, name: string, description?: string) {
  return await this.agentModel.create({
    userId: userId,
    name,
    description,
    knowledgeBaseId: this.configService.get('SHARED_KNOWLEDGE_BASE_ID'),
    dataSourceId: this.configService.get('SHARED_DATA_SOURCE_ID'),
  });
}
Enter fullscreen mode Exit fullscreen mode

Multi-Model Support

Users can choose different AI models while sharing the same knowledge base:

// User can select Claude, Mistral, Titan, etc.
const selectedModelKey = modelKey || session.modelKey || 'claude3Sonnet';
Enter fullscreen mode Exit fullscreen mode

User Registration

New users automatically get access to the shared infrastructure:

await this.userModel.create({
  cognitoId: response.UserSub,
  username: username,
  email: email,
  // Pool pattern benefits - instant access to shared resources
  tier: 'starter',
  maxAgents: 5,
  maxDocuments: 100,
  maxMessagesPerMonth: 1000,
});
Enter fullscreen mode Exit fullscreen mode

Why This Works

  1. Cost Efficient: One Knowledge Base serves hundreds of tenants
  2. Simple Onboarding: New user? Just start uploading - no setup needed
  3. Flexible: Each tenant can use different AI models
  4. Secure: Metadata filtering ensures complete data isolation

Critical Success Factor

The .metadata.json file is crucial. Without it:

  • Documents won't be filterable by tenant
  • Data isolation breaks
  • The entire multi-tenant system fails

Always ensure every document has its corresponding metadata file with the correct userId and agentId.

👨‍💻 Connect with me:
🖥️ Website
📌 LinkedIn
📂 GitHub
📝 Blog

Top comments (0)