What is Multi-Tenant Architecture (Multi-Tenancy)?
A software architecture where one running instance of an application, and usually its infrastructure, serves many customers (tenants), with each tenant's data and configuration kept logically isolated. It is the default model for SaaS.
Definition
Multi-tenancy means a single deployment of an application serves many customers at once. Each customer is a tenant: usually an organization, team or workspace, not an individual user. Many users from one company form one tenant. The tenants share code, servers and often the same database, but each one sees only its own data, settings and users, as if it had a private copy of the product. The opposite is single-tenant architecture, where every customer gets a separate deployment: its own application instance, database and sometimes its own cloud account. Single-tenant setups give strong isolation and easy per-customer customisation, but every new customer adds servers to patch, migrations to run and costs to carry. Multi-tenancy trades some isolation for economies of scale: one codebase, one upgrade, one fleet to monitor. In practice multi-tenancy is a spectrum rather than a yes/no choice. AWS's SaaS guidance describes three models. In the silo model each tenant gets dedicated resources, such as a separate database or a full stack, while still sharing onboarding, identity and operations. In the pool model tenants share the same infrastructure, and isolation is enforced in software. The bridge model mixes the two: for example, a regulated or noisy service is siloed while the rest is pooled. At the data layer the common patterns are: a shared database and shared schema with a tenant_id column on every table; a shared database with one schema per tenant; and one database per tenant. The shared-schema approach is the cheapest and simplest to operate at large tenant counts, but a single missing WHERE tenant_id = ? clause can leak data between customers. Database features such as PostgreSQL row-level security (RLS) let you enforce the tenant filter inside the database instead of trusting every query. Multi-tenancy also touches everything around the data: authentication has to resolve which tenant a request belongs to (by subdomain, path, token claim or header), authorization has to check permissions within that tenant, caches and queues need tenant-aware keys, and rate limits and quotas need to stop one heavy tenant from slowing everyone else down, the "noisy neighbour" problem.
When to Use Multi-Tenant Architecture (Multi-Tenancy)
Use "multi-tenant" for a system where tenants share an application instance and some infrastructure, and "single-tenant" when each customer gets a dedicated deployment. Vendors sometimes say "dedicated" or "isolated" tenancy for a siloed, single-tenant option sold at a higher price tier. Choosing a data isolation model: - Shared schema with tenant_id: best for many small tenants (self-serve SaaS, free tiers). Cheapest, one migration for everyone. Needs strict query discipline or row-level security. - Schema per tenant: middle ground. Easier per-tenant backup and restore, but migrations must run across every schema and catalogue size grows with tenant count. - Database per tenant: strongest isolation and easiest per-tenant restore, data residency and deletion. Highest operational cost; usually reserved for enterprise or regulated customers. Many products end up hybrid: pooled for the long tail of small customers, siloed for large enterprise contracts that demand dedicated resources or a specific region. Practical rules that save pain later: - Put tenant_id on every tenant-owned table from day one, including join tables, and include it in indexes and unique constraints (for example UNIQUE (tenant_id, email)). - Resolve the tenant once, early in the request (middleware), and pass it through context rather than reading it from user input in each handler. - Enforce isolation in more than one place: application query scoping plus database RLS, or separate credentials per tenant. - In PostgreSQL, remember that table owners and superusers bypass RLS by default; connect your app with a non-owner role or use FORCE ROW LEVEL SECURITY. - Make caches, object storage paths, search indexes, queues and logs tenant-aware, and add per-tenant rate limits and usage metrics. - Write automated tests that try to read another tenant's data and must fail.
Multi-Tenant Architecture (Multi-Tenancy) in Practice
- Shared-schema SaaS: a projects table with a tenant_id column and a PostgreSQL policy such as USING (tenant_id = current_setting('app.tenant_id')::uuid), so every query is filtered by the database itself.
- Schema-per-tenant: a B2B app that creates a PostgreSQL schema like tenant_acme for each customer and sets search_path per request.
- Database-per-tenant: an enterprise tier where each large customer gets its own database, or its own cluster in a chosen region, for data residency.
- Tenant resolution by subdomain: acme.example.com and globex.example.com hit the same app servers, and middleware maps the host to a tenant record.
- Workspaces and organizations in tools like Slack or GitHub behave as tenants from the user's point of view: one login can belong to several, and data is scoped to each.
- A shared Kubernetes cluster where business units are tenants, isolated with namespaces, RBAC, network policies and resource quotas.
Common Mistakes
- Relying only on application code to add tenant filters. One forgotten WHERE clause leaks data across customers; back it up with row-level security or separate credentials.
- Testing RLS as the table owner or a superuser. In PostgreSQL those roles bypass row security by default, so tests pass while production may not be protected as expected, or the reverse.
- Forgetting tenant-aware cache keys, file paths and search indexes, so one tenant's cached page or file is served to another.
- Leaving out per-tenant quotas and rate limits, letting a single heavy tenant degrade performance for everyone (the noisy neighbour problem).
- Choosing database-per-tenant for a self-serve product with thousands of small customers, then drowning in migrations, connections and backups.


