Blog

Multi-Tenant Architecture with Claude Code

How Claude Code helps design and implement row-level, schema-level, and database-level multi-tenancy, with a pattern comparison table covering tradeoffs.

Phos Team ·
claude code

Multi-tenancy is not a single architectural decision. It is a cluster of decisions about data isolation, operational complexity, cost, and compliance that compound across the lifetime of a product.

Getting the isolation level wrong at the start is expensive to fix. Choosing database-level isolation when row-level would have served equally well adds infrastructure cost and operational overhead for no compliance benefit.

Claude Code accelerates the implementation of whichever pattern fits your requirements. The pattern selection is still yours.

Any multi-tenant system needs a solid authentication layer underneath, the authentication implementation guide covers how to generate and harden auth with Claude Code.


The three multi-tenancy patterns

Each pattern sits at a different point on the isolation-versus-cost tradeoff curve. Understanding what each pattern provides is the foundation for making the right choice before any code is generated.

Row-level isolation

All tenants share one database and one schema. Tenant identity is a column on every shared table.

Application middleware injects a tenant_id filter on every query.

Row-level isolation is the fastest to implement, the cheapest to operate, and the most common starting point for early-stage SaaS products.

The tradeoff: a missing WHERE clause in application code leaks one tenant’s data to another. The isolation boundary is entirely in your application logic, not in the database.

Schema-level isolation

All tenants share one database. Each tenant has their own schema (in PostgreSQL terminology) or database schema namespace.

Tables are replicated per tenant within the shared database server.

Schema-level isolation provides a stronger database-level boundary than row-level. A query running in tenant A’s schema cannot access tenant B’s schema without explicit cross-schema access.

The tradeoff: schema migrations must run per tenant. With 500 tenants, a migration runs 500 times.

Migration management tooling becomes a required operational component.

Database-level isolation

Each tenant has their own database server or isolated database instance. No data sharing at the infrastructure level.

Database-level isolation satisfies the strictest compliance requirements (HIPAA Business Associates, financial services data segregation). It also costs the most to operate and adds the most infrastructure complexity.

The tradeoff: provisioning a new tenant requires provisioning a new database. Connection pooling per tenant, migration management per database, and backup management per database are all required operational components.

Start with the minimum isolation level that satisfies your compliance and contractual requirements. Moving from row-level to schema-level is a significant migration. Moving from schema-level to database-level is harder still. Get the level right before you scale.


Pattern comparison table

DimensionRow-levelSchema-levelDatabase-level
Implementation complexityLowMediumHigh
Operational complexityLowMediumHigh
Infrastructure costLowestMediumHighest
Data isolation strengthApplication layerDatabase schemaInfrastructure
Migration complexityOne migrationPer-schema migrationPer-database migration
Compliance fitStandard SaaSHigher-sensitivity B2BHIPAA, financial, defense
Tenant onboarding speedInstantSeconds (schema create)Minutes (DB provision)
Performance isolationNoneLimitedFull
Best forEarly-stage, SMB customersMid-market B2BEnterprise, regulated

How Claude Code helps design each pattern

Row-level isolation implementation

Claude Code generates the full row-level implementation from a structured prompt:

Implement row-level multi-tenancy for this PostgreSQL/Prisma application:
- tenant_id UUID column on all shared tables
- Middleware to inject authenticated tenant context
- Prisma client extension that adds WHERE tenant_id = ? to all queries
- Row-level security policies at the database level as a backup
- API endpoint to return only the requesting tenant's data

The most valuable generated component is the Prisma client extension (or equivalent ORM query wrapper). This ensures the tenant filter is applied at the data access layer rather than repeated at every query site.

Claude Code also generates PostgreSQL row-level security policies as a defense-in-depth layer. These are database-level constraints that catch tenant_id omissions in application code.

Schema-level isolation implementation

Schema-level requires more infrastructure management. Claude Code generates:

  • Tenant provisioning scripts. Create schema, run migrations in schema context.
  • Connection string management per tenant schema.
  • Migration tooling that iterates over all tenant schemas.
  • Application middleware that routes requests to the correct schema.
Generate schema-level multi-tenancy for this Node.js/PostgreSQL application:
- Tenant schema provisioning function (create schema, seed base tables)
- Search path middleware to set schema context per request
- Migration runner that executes against all tenant schemas
- Tenant registry table in the public schema

The generated migration runner is typically the component that needs the most review. Verify that it handles partial migration failures (some schemas migrated, others not) and provides rollback capability.

Database-level isolation implementation

Database-level isolation shifts significant complexity to infrastructure provisioning. Claude Code generates the application-layer components:

  • Tenant registry with encrypted connection string storage.
  • Connection pool management per tenant database.
  • Tenant provisioning orchestration that calls your infrastructure API to provision the database, then seeds it.
  • Health check logic across all tenant databases.
Generate database-level multi-tenancy scaffolding:
- Tenant registry service with encrypted connection string storage
- Dynamic connection pool that resolves the correct database per request
- Provisioning service that integrates with [AWS RDS / Supabase / PlanetScale]
- Tenant isolation test suite verifying cross-tenant data access is impossible

For infrastructure provisioning (the actual database creation), Claude Code generates Terraform or Pulumi modules if you specify your infrastructure platform.


The workflow: from requirements to running isolation

Step 1: Define isolation requirements

Before any code generation, answer these questions explicitly:

  • What compliance frameworks govern your data handling? (SOC 2, HIPAA, ISO 27001)
  • Do your customer contracts include data isolation commitments?
  • What is your current tenant count and projected count at 12 months?
  • Is performance isolation (one tenant’s heavy queries affecting another) a requirement?

These answers determine the pattern. Bring them into the Claude Code conversation.

Step 2: Generate the data model

Start with the data model before any middleware:

Based on [row-level / schema-level / database-level] isolation:
Generate the Prisma schema for a [your domain] application with:
- Tenant entity and configuration
- [Core domain entities] with appropriate tenant relationship
- Indexes optimized for tenant-scoped queries

Review the generated schema for completeness before proceeding to middleware.

Step 3: Implement the middleware layer

The tenant resolution middleware is the most security-critical generated component. It must correctly identify the tenant on every request before any data access occurs.

Generate tenant resolution middleware that:
- Extracts tenant identity from [JWT claim / subdomain / custom header]
- Validates the tenant is active and the requesting user belongs to it
- Injects tenant context into the request for downstream use
- Returns 401/403 for invalid or unauthorized tenant access

Test this middleware exhaustively before wiring in the data layer.

Step 4: Generate and verify isolation tests

Claude Code generates cross-tenant isolation tests that attempt to access data across tenant boundaries:

Generate isolation tests verifying:
- Tenant A user cannot read Tenant B's records
- Tenant A user cannot write to Tenant B's records
- Requests with no tenant context are rejected
- Admin users accessing tenant data leave audit trail

These tests are the primary verification mechanism. Run them as part of every CI pipeline.


What needs human judgment

  • Compliance interpretation. Row-level security with proper application controls satisfies many compliance frameworks. Whether it satisfies yours requires reading the actual framework requirements, not a general comparison table. For teams building multi-tenant products at scale, the enterprise development guide covers additional compliance and governance considerations. The security best practices guide is also a useful reference for hardening generated isolation code.
  • Migration strategy. For schema-level and database-level patterns, migration execution order and rollback strategy across dozens or hundreds of tenants is an operational plan, not a code generation task.
  • Tenant offboarding. Claude Code generates tenant provisioning. Data deletion, export, and offboarding (required by GDPR and many customer contracts) must be explicitly specified and tested.

Frequently asked questions

Can Claude Code migrate us from row-level to schema-level isolation?

Claude Code can generate the migration scripts and backfill logic. The migration itself involves moving production data, which is a high-risk operation regardless of how the scripts are generated.

Treat the generated migration as a starting point, test it against a production-sized dataset in a staging environment, and plan for a maintenance window.

How does Claude Code handle the tenant context in serverless environments?

Serverless functions lack persistent connections, which affects connection pooling strategies in all three isolation patterns. Specify your serverless platform in the prompt and Claude Code adjusts the generated code accordingly.

For database-level isolation in serverless, connection overhead per function invocation is a real cost. The generated code should use a connection proxy layer (PgBouncer, RDS Proxy) rather than direct connections.

What about row-level security in databases other than PostgreSQL?

PostgreSQL’s RLS is the most fully featured among common databases. MySQL lacks native RLS. The application middleware layer carries the full isolation burden.

SQLite is single-writer and not suitable for multi-tenant production use. Specify your database in the prompt and Claude Code generates the appropriate isolation approach for that database’s capabilities.

Does Claude Code generate tenant-scoped caching correctly?

Caching is a common source of cross-tenant data leakage. Claude Code generates cache key patterns that include tenant_id when requested explicitly.

Include tenant-scoped caching with cache key isolation in your generation prompt to ensure cache keys cannot collide across tenants.


Ready to build your multi-tenant architecture?

The isolation pattern decision comes before any code. The workflow and generated components above apply once that decision is made.

Path one: build it yourself. Use the pattern comparison table to select your isolation level, follow the four-step workflow above, and use the generated isolation tests as your verification mechanism.

Path two: work with Phos AI Labs. We architect multi-tenant systems using Claude Code as part of a structured engagement. Requirements, isolation pattern selection, implementation, and testing are handled together. Book a discovery call.

Related articles

The fastest way to know whether we're the right fit, is a conversation.

STEP 1/2 · ABOUT YOU