Founder & Lead Engineer, RAITHub
Choose multi-tenant SaaS by default: one shared deployment serves every customer, so running cost per tenant falls as you grow and every customer gets each release at once. Choose single-tenant, a dedicated stack per customer, only when a contract, regulator or data-residency rule demands it, or when a few large customers pay enough to cover a fleet you must patch, monitor and back up separately.
This post is the decision one level above the database. The multi-tenant SaaS guide already compares shared schema, schema per tenant and database per tenant. Here the question is wider: does a customer share your running product with everyone else, or get a copy of their own? It covers what each choice costs at 10, 100 and 1,000 customers, how each handles a noisy neighbour and a one-customer restore, when compliance really forces dedicated infrastructure, and how to move a customer from one model to the other without a rewrite.
What is the difference between multi-tenant and single-tenant SaaS?
In multi-tenant SaaS, all customers (tenants) use one shared deployment and the software keeps their data apart. In single-tenant SaaS, each customer gets dedicated infrastructure: their own application instances, their own database, sometimes their own cloud account.
AWS names the two ends and the middle in its SaaS Lens. The silo model "refers to an architecture where tenants are provided dedicated resources"; the pool model is where "tenants share resources"; and the bridge model is a mixed mode where some parts are siloed and others pooled. One point in that definition matters more than it looks: a silo "still relies on a shared identity, onboarding, and operational experience". Single-tenant SaaS is still one product run by one team. If every customer runs a different version with its own onboarding and its own release process, you have a managed-services business, and your costs will behave like one.
Multi-tenant or single-tenant: which should you choose?
Start pooled, and move individual customers to dedicated infrastructure when one of the rows below forces it. The table is the checklist RAITHub uses when this question comes up on an architecture call.
| Factor | Points to multi-tenant (pool) | Points to single-tenant (silo) |
|---|---|---|
| Number of customers | Dozens to thousands, growing | A handful, each large |
| Revenue per customer | Small or medium contracts | Large enough to pay for a dedicated stack and its upkeep |
| Contractual isolation | Buyers accept logical separation with evidence | The contract names a dedicated database, network or account |
| Data residency | All customers can live in one region, or a few regional pools | Individual customers need their own region or cloud account |
| Encryption keys | Provider-managed keys are acceptable | The customer must hold or revoke its own keys |
| Release cadence | Everyone on the same version, shipped continuously | Customers demand change windows or approval before upgrades |
| Customisation | Configuration and feature flags are enough | Real per-customer code or schema differences (usually a warning sign) |
| Operations team | Small; one deployment to watch | Automation mature enough to run a fleet |
| Noisy-neighbour tolerance | Quotas and rate limits are acceptable | A customer's load must never affect another's, or be affected |
| One-customer restore | Occasional and can take a few hours | Must be routine, fast and provable per customer |
Microsoft's tenancy models guide makes the same point from the other side: "Selecting a tenancy model isn't only a technical decision. It's also a commercial decision." If only one customer in twenty needs a silo, that is a pricing tier, not an architecture.
How does the cost change as you add tenants?
Single-tenant cost grows in a straight line with customers; multi-tenant cost grows much more slowly. Microsoft's guide puts it plainly: "If a single tenant requires a specific infrastructure cost, 100 tenants probably require 100 times that cost."
The table shows the shape with round numbers. The figures are illustrative assumptions, not prices from any provider: a dedicated stack with a floor of $150 a month (small app instances, a small database, monitoring and backups), and a shared deployment with a $400 base plus $5 a month of extra capacity per tenant.
| Tenants | Single-tenant (assumed $150 each) | Multi-tenant (assumed $400 + $5 each) | Deployments to patch |
|---|---|---|---|
| 10 | $1,500 a month | $450 a month | 10 vs 1 |
| 100 | $15,000 a month | $900 a month | 100 vs 1 |
| 1,000 | $150,000 a month | $5,400 a month | 1,000 vs 1 |
The last column is the cost the invoice does not show. Every dependency upgrade, security patch, schema migration and configuration change runs once per deployment. At ten customers a script and a careful afternoon cover it. At a thousand you need a deployment pipeline that treats the fleet as data, tracks which version each customer runs, and retries failures, and you need people to watch it.
Shared infrastructure is not free of scaling costs either. The same Microsoft guide warns that "the costs of scaling might increase nonlinearly" for a single shared database at high scale. That is the moment to split the pool into several pools, called stamps or cells, rather than give every customer a silo.
How do you stop a noisy neighbour in multi-tenant SaaS?
With per-tenant limits enforced by the platform, per-tenant monitoring, and the option to move a heavy tenant into its own pool. The noisy neighbour antipattern is "when one tenant's performance is degraded because of the activities of another tenant", and Microsoft is clear that sharing "inherently carries the risk of noisy neighbor problems that you can't completely avoid".
What works in practice:
- Rate limits keyed on tenant, not only on user or IP. One customer's integration script should hit its own ceiling. On serverless hosting the counter must be shared across instances; the approach is in rate limiting without Redis on serverless.
- A time limit on every tenant query. A report that scans a year of data should fail for that tenant, not hold locks for everyone.
- Fair queues for background work. Exports and imports go into per-tenant queues, or a shared queue with a per-tenant concurrency cap, so one bulk import cannot starve every other customer's emails.
- Metrics tagged with the tenant. You cannot move a heavy tenant you cannot identify.
The query time limit can live in the same helper that sets the tenant for row-level security, so it is impossible to forget:
await db.query('BEGIN')
await db.query("SELECT set_config('app.tenant_id', $1, true)", [tenantId])
// Transaction-scoped, like the tenant setting: gone at COMMIT or ROLLBACK.
await db.query("SET LOCAL statement_timeout = '5s'")
Single-tenant avoids the problem by construction, which is why customers with spiky, heavy workloads are the usual first candidates for a silo.
Can you back up and restore one customer on its own?
With single-tenant, yes, natively: each customer's database has its own backups and point-in-time recovery. With multi-tenant, you restore the whole database somewhere safe and copy one tenant's rows back, which works but has to be rehearsed.
The difference shows up on the worst day. A customer's admin bulk-deletes three months of records by mistake and asks for them back. On a silo you restore that customer's database to ten minutes before the mistake, and nobody else notices. On a pool you cannot roll the shared database back, because every other customer kept working in those ten minutes. You restore last night's backup into a scratch database, export that tenant's rows table by table, and write them back into production inside that tenant's context, so row-level security guarantees the restore cannot touch anyone else.
If your contracts promise per-customer recovery times, write down the pooled procedure, time it on real data sizes, and repeat the drill every quarter. If you cannot meet the promise on a pool, that customer belongs on a silo.
When does compliance force single-tenant infrastructure?
Less often than sales teams fear. In our reading, most security frameworks and data-protection rules ask for adequate separation, access control and evidence, rather than naming an architecture. The demand for a dedicated instance usually comes from a specific buyer's own policy or contract. This is general information; confirm your own obligations with your adviser.
Microsoft's example is software for legal firms, whose customers "might insist on having their own dedicated infrastructure to maintain compliance with regulatory requirements". Clauses that genuinely push towards a silo:
- Customer-managed keys with the right to revoke them, cutting off only that customer's data.
- Data pinned to one region or one cloud account the customer can audit.
- Network isolation, such as private connectivity from the customer's own network.
- Change approval, where the customer signs off each upgrade in a maintenance window.
- Penetration testing by the customer against an environment that holds no one else's data.
Clauses that usually do not: "our data must be logically separated", "you must restrict staff access", "you must keep an audit log". A pooled design with database-enforced isolation and tests answers those. How to prove it to a reviewer is in SaaS security best practices, and what to do if isolation has already failed is in users can see another tenant's data.
How do you move from single-tenant to multi-tenant, or back?
Both directions are data migrations, and both are much easier if every table already carries a tenant_id and every ID is globally unique. Those two habits cost almost nothing on day one.
Single-tenant to multi-tenant (consolidation)
- Add
tenant_idto every table in every silo, backfilled with that silo's tenant. - Fix ID collisions. Auto-increment IDs overlap across silos: invoice 1041 exists in all of them. Re-key to UUIDs, or remap IDs on import and keep a mapping table for old links.
- Turn on row-level security in the pooled database before the first tenant arrives, following the Postgres row-level security guide.
- Move one tenant at a time, smallest first: freeze writes, copy, compare row counts and checksums per table, switch routing, keep the silo read-only for a rollback window.
- Delete the silo only after the retention period your contracts require.
Multi-tenant to a dedicated deployment (the bridge)
- Add a tenant placement record in a control-plane table: which database or deployment serves each tenant.
- Provision the silo from the same infrastructure code and the same schema version as the pool.
- Copy the tenant's rows, parents before children, then freeze writes briefly, copy the changes, and verify counts.
- Flip the placement record, watch errors, then remove the tenant's rows from the pool after the rollback window.
Keep tenant_id and row-level security in the silo too. The same code then runs in both places, and the customer can move back to the pool if the contract changes.
What does a hybrid of pooled and dedicated tenants look like in code?
One code path, with a lookup that picks the database for each tenant. The placement comes from your own control-plane table, never from the request.
import { Pool } from 'pg'
type Placement =
| { mode: 'pooled' }
| { mode: 'dedicated'; databaseUrl: string }
const shared = new Pool({ connectionString: process.env.DATABASE_URL, max: 10 })
const dedicated = new Map<string, Pool>()
// Placement is read from the control plane and cached briefly.
export function poolFor(tenantId: string, placement: Placement): Pool {
if (placement.mode === 'pooled') return shared
let pool = dedicated.get(tenantId)
if (!pool) {
// Small per-tenant pools: many silos multiply open connections.
pool = new Pool({ connectionString: placement.databaseUrl, max: 2 })
dedicated.set(tenantId, pool)
}
return pool
}
Everything else, from setting the tenant context to running queries, is identical. That is what keeps a bridge model from turning into two products.
Why RAITHub for this decision
Because RAITHub builds pooled, database-isolated platforms and tests the boundary on every build, and will tell you when a silo is worth paying for.
- Pooled isolation in production. Sundor Skin keeps every business buyer apart with PostgreSQL row-level security across 146 tables, with 530+ automated tests. BlockEstate treats each brokerage as a tenant on one shared platform, and reached MVP in 6 weeks.
- Honest about the other side. RAITHub's shipped platforms use the shared model. The dedicated-deployment guidance above is engineering guidance, not a case study.
- Decided in writing. The tenancy model and placement design go into the architecture spec you sign before production code; see the SaaS development service.
- Fixed scope, your IP. A free 15-minute technical audit, then a fixed written quote. You own the code, and an NDA is standard.
When you don't need us
- You have one customer. An internal tool for one company is single-tenant by nature; skip the tenancy machinery.
- A buyer asked for "dedicated" but meant "separate". Ask what the clause is protecting. Often a written isolation model and a demo settle it without any new infrastructure.
- You need someone to run a large single-tenant fleet day to day. That is an operations contract, and RAITHub does not offer staff augmentation.
If you are choosing a tenancy model now, or a buyer's contract is pushing you towards a dedicated deployment, book the free technical audit and bring the clause.
Written 29 September 2026. Sources checked on 29 September 2026.
Frequently asked questions
Is multi-tenant SaaS less secure than single-tenant?
Not inherently. Multi-tenant puts more weight on software isolation, so it must be enforced in the database and tested on every build. Single-tenant removes one class of bug, cross-tenant leaks, but adds fleet risks such as unpatched or misconfigured instances.
Is single-tenant SaaS more expensive?
Almost always. Infrastructure grows roughly in line with the number of customers, and every patch, migration and upgrade runs once per deployment. Charge for it as a separate tier.
Can I offer both models in one product?
Yes. This is the bridge or hybrid model: most tenants share a pool and a few run on dedicated infrastructure, served by the same code through a placement lookup. It is easiest when every table carries a tenant ID from day one.
Does GDPR require single-tenant hosting?
In our reading, no; it asks for appropriate technical and organisational measures rather than a specific architecture. Individual customers may still require dedicated hosting by contract. This is general information; confirm with your adviser.
How do I restore one customer's data in a multi-tenant database?
Restore a backup into a scratch database, export that tenant's rows table by table, and write them back into production inside that tenant's context so row-level security blocks any cross-tenant write. Rehearse it before a customer needs it.
When should a tenant move to dedicated infrastructure?
When its contract requires it, when its load keeps affecting other tenants despite limits, or when it needs a per-customer recovery time a shared database cannot meet. Price the move so the customer pays for the silo.
Related posts
PostgreSQL Row-Level Security for Multi-Tenant SaaS, with Tests
13 min readTurning a Single-Tenant App Into Multi-Tenant SaaS Without a Rewrite
12 min readOne Platform, Many Agencies: Tenant Isolation for Property Portals
18 min readReady to discuss your project?
Book a free 15-minute technical audit with our engineering team.