Multi-Tenant AI Architectures for Consulting Firms
If you’re a consulting firm, a software-as-a-service company, or any business serving multiple clients, you can’t build a separate AI system for each one. You need a multi-tenant architecture: one codebase, one set of infrastructure, multiple isolated clients.
This is hard. Most teams get it wrong. They create isolated databases per client, duplicate Lambda functions, or use crude string filtering for data access control. Then they discover their cost model is broken (each tenant is oddly expensive), or security is leaky, or scaling is impossible.
I’ve built multi-tenant AI systems for three consulting clients. Here’s the pattern that works.
The Challenge
You have 20 clients. Each has their own documents to process, their own data, their own outputs.
You need to:
- Keep client data separated (they shouldn’t see each other’s documents)
- Track costs per client (who pays for what?)
- Scale independently (one busy client shouldn’t slow others down)
- Deploy once, run for all clients (not 20 separate systems)
- Isolate failures (if tenant A’s data breaks processing, don’t break tenant B)
Most architects try to solve this with different databases per tenant. That’s wrong. You’ll end up managing 20 databases, 20 Lambda functions, 20 CloudWatch dashboards. A nightmare.
The Right Model
Single database. Multiple tenants. Partition key strategy.
DynamoDB makes this easy:
All tenant A’s documents have partition key “tenant-abc”. All tenant B’s documents have partition key “tenant-xyz”.
Your code queries by partition key. Tenant data is automatically isolated.
Cost tracking is automatic. You tag every DynamoDB write with the tenant_id, then aggregate billing by tenant.
The Complete Architecture
Step 1: Authorization
Every request includes a tenant_id. Could come from:
- Bearer token (JWT with tenant info)
- API key (mapped to tenant in a lookup table)
- URL path (/api/tenants/{tenant_id}/documents)
Your first Lambda function validates that the caller has access to this tenant:
Step 2: Processing
The processing Lambda always receives an authenticated tenant_id. It processes the document and stores results tagged with the tenant:
Step 3: DynamoDB Partition Strategy
Your table structure:
Every item includes tenant_id. Your queries always filter by tenant. Data isolation is automatic.
Cost Attribution
Multi-tenant systems can be tricky to bill. How much did processing documents for tenant A actually cost?
Use tagging and cost allocation:
Track:
- Claude API cost (# tokens × rate)
- Lambda invocations (# invocations × rate)
- DynamoDB writes (# writes × rate)
- S3 storage (# GB × rate)
Aggregate by tenant. You can now tell tenant A exactly what they cost you.
Rate Limiting and Quotas
Prevent one tenant from overwhelming the system:
Failure Isolation
If tenant A’s data causes Claude to return garbage, don’t let it crash the system for tenant B.
Use Lambda’s concurrency reservation to isolate tenants:
Alternatively, use SQS with per-tenant queues:
Terraform Modules for Tenant Provisioning
When you add a new tenant, create a module that provisions all their infrastructure:
The module looks like:
Data Retention and Cleanup
Different tenants might have different data retention policies. Use DynamoDB TTL:
DynamoDB automatically deletes expired items. Configure TTL per tenant if retention periods differ.
Scaling Multi-Tenant Systems
With partition key = tenant_id, DynamoDB’s hot partition problem is solved by design. Each tenant’s data is in a separate partition.
But if one tenant’s processing is resource-intensive (e.g., processing 100,000 documents at once), it could impact others.
A few options handle this. Reserve concurrent Lambda capacity per tenant so one client can’t starve the others. Give each tenant their own SQS queue and process it serially. Or route high-volume tenants to a separate Lambda alias entirely, so their load never touches the shared pool.
For most SaaS/consulting use cases, concurrency reservation is enough.
The Bottom Line
Multi-tenant AI systems are not simple. But they’re necessary if you’re serving multiple clients.
The architecture comes down to a few rules. One codebase, one set of infrastructure, deployed once. A tenant_id on every request, filtered at every layer. DynamoDB partitioned by tenant for automatic isolation. Cost tracked and billed per tenant through metrics. Failures contained so one tenant’s problems stay that tenant’s problems. And a Terraform module that provisions a new tenant without touching the others.
Build this right, and you can serve 100 tenants with the same infrastructure that serves one.
Ready to build a multi-tenant AI system? Book a call and I’ll help you design the architecture for serving multiple clients at scale.
Get the free AI Readiness Checklist
15 questions to diagnose your team’s AI readiness, where you’ll see ROI fastest, and what to tackle first.
No spam. Unsubscribe anytime.
Ready to build AI that actually works?
Let’s talk about how SRE discipline transforms AI from a risky experiment into a reliable business system.
Book Your Free Discovery Call