Building Multi-Tenant APIs: Architecture Patterns
Building Multi-Tenant APIs: Architecture Patterns
Multi-tenant APIs serve multiple customers (tenants) from a single deployment. Every B2B SaaS product is multi-tenant. The core challenge: keeping tenant data isolated while sharing infrastructure efficiently. Get it wrong and Customer A sees Customer B's data.
Database Isolation Strategies
1. Shared Database, Shared Schema
All tenants share one database and tables. A tenant_id column on every table separates data.
SELECT * FROM orders WHERE tenant_id = 'tenant_123' AND id = 'order_456';
Pros: Simplest. Cheapest. Easy to deploy and maintain.
Cons: Hardest to isolate. One missing WHERE tenant_id = clause leaks data. Noisy neighbor risk (one tenant's heavy query slows everyone).
Use when: Early-stage SaaS, small tenants, cost matters more than isolation.
2. Shared Database, Separate Schemas
Each tenant gets their own database schema (namespace). Tables are identical but isolated.
SET search_path TO tenant_123;
SELECT * FROM orders WHERE id = 'order_456';
Pros: Better isolation than shared schema. Schema-level security. Easier per-tenant migrations. Cons: Many schemas to manage. Connection pooling across schemas is complex. Backup/restore is per-schema.
Use when: Medium-sized tenants needing data isolation without separate databases.
3. Separate Databases
Each tenant gets their own database instance. Complete isolation.
Pros: Strongest isolation. Per-tenant performance tuning. Simplest compliance story. Cons: Most expensive. Connection management across databases. Cross-tenant queries impossible.
Use when: Enterprise tenants, regulated industries (healthcare, finance), tenants with specific compliance requirements.
API-Level Patterns
Tenant Resolution
How does the API know which tenant a request belongs to?
| Method | Example | Best For |
|---|---|---|
| Subdomain | acme.api.example.com | Customer-facing APIs |
| Header | X-Tenant-Id: acme | Internal/B2B APIs |
| API key | Key maps to tenant | Developer APIs |
| JWT claim | tenant_id in token | OAuth-based APIs |
| URL path | /api/tenants/acme/users | Admin APIs |
Tenant-Scoped Authorization
Every request must be scoped to the authenticated tenant. Implement as middleware that runs before any business logic.
Per-Tenant Rate Limiting
Different tenants get different rate limits based on their plan:
Free tenant: 100 requests/hour
Pro tenant: 10,000 requests/hour
Enterprise tenant: 100,000 requests/hour
Data Isolation Enforcement
The most critical rule: never trust the application layer alone for data isolation. Use database-level enforcement (Row Level Security in PostgreSQL, separate schemas, or separate databases) as a safety net.
Common Mistakes
| Mistake | Impact | Fix |
|---|---|---|
Missing tenant_id in query | Data leak across tenants | RLS, middleware enforcement |
| Global admin without tenant scope | Access to all tenant data | Explicit tenant context even for admins |
| Shared cache without tenant key | Cache poisoning across tenants | Include tenant_id in all cache keys |
| No per-tenant rate limiting | One tenant impacts others | Tenant-scoped rate limits |
| Shared background jobs | Job failures affect all tenants | Tenant-isolated job queues |
Building SaaS APIs? Explore API architecture patterns on APIScout — guides, comparisons, and developer resources.