What database-per-tenant actually costs
The real cost of a database per tenant: infra bills, connection pooling, ops load, and the tenant count where it stops paying for itself.
In short
Database-per-tenant costs more than the database line item - raw hosting is often the smallest part. Connection pooling, per-tenant backups, monitoring and migration supervision add up fast, and past a certain tenant count the ops overhead outweighs the infrastructure bill itself.
Database-per-tenant looks cheap on the pricing calculator. Pick a small managed instance, multiply by the tenant count, and the number that comes out is usually smaller than people expect. That number is also not the bill. The same blind spot shows up whenever a sticker price stands in for the real cost - totaling an assembled auth-and-billing stack hits it too, just with vendor subscriptions instead of database instances, and so does pricing self-hosting against a managed plan, with ops hours standing in for the subscriptions.
And the sticker really is small. PlanetScale sells a single-node Postgres cluster for $5 a month, a Supabase Pro project - a dedicated Postgres instance - starts at $25, and a Neon database that has scaled to zero bills $0 for compute while it sleeps (each figure verified 24 September 2026 on the vendor's pricing page). A hundred tenants at five dollars each is $500 a month, which most teams would sign off without a meeting. That is the number the calculator gives you, and it is the least important number in this post.
The assumptions
Every input here is stated so you can swap in your own and recompute.
- A fully loaded senior engineer costs $150 an hour. This is a common loaded-cost assumption for US engineering time (salary, benefits, overhead) rather than a sourced vendor figure - halve it if your team's real number is lower, the shape of the argument does not change.
- One managed Postgres instance per tenant, the pattern the whole post is about. Not a connection-pooled shared cluster, not schema-per-tenant on one instance - a genuinely separate database per customer.
- A routine schema change happens roughly once a month. Adding a column, adding an index, backfilling a default - the kind of migration most SaaS products ship regularly, not a rare rewrite.
- 1% of nightly backup jobs need a human look in a given month - a stalled job, a size anomaly, a restore test that fails. That rate is a guess, not a benchmark; if your real failure rate is different, the backup line moves with it.
- Three tenant counts examined: 100, 1,000 and 10,000 - roughly where a new product, a growing one, and a mature multi-tenant SaaS sit.
The arithmetic
The database instance cost is real but it is not where this pattern gets expensive. What scales with tenant count is supervision time, and it scales because every operation that would be "run once" on a shared database becomes "run N times, watched" on N databases.
| Tenant count | Pooling upkeep | Backup triage | Migration supervision | Monitoring/alerting | Total labor | Ops cost @ $150/hr |
|---|---|---|---|---|---|---|
| 100 | 1 hr | 0.25 hr | 1.7 hr | 0.5 hr | ~3.4 hr | ~$510 |
| 1,000 | 2 hr | 2.5 hr | 16.7 hr | 2 hr | ~23 hr | ~$3,450 |
| 10,000 | 4 hr | 25 hr | 167 hr | 8 hr | ~204 hr | ~$30,600 |
How each column is built:
- Pooling upkeep. Every managed Postgres instance caps total open connections in the low hundreds without an external pooler. N databases means N connection ceilings, so past a few hundred tenants you are running and re-tuning a pooler (PgBouncer or equivalent) rather than relying on the database's own limit. The hours here are re-tuning and capacity review, not first-time setup.
- Backup triage. One backup job per database, each with its own retention policy and point-in-time-recovery target. At the assumed 1% failure rate, 10,000 databases produce 100 failures a month to investigate at roughly 15 minutes each.
- Migration supervision. A migration against a shared database runs once. Against database-per-tenant it has to run, or be orchestrated to run, once per database - with concurrency limits so you do not take every tenant offline at the same instant. At roughly one minute of supervised rollout time per database, this is the column that dominates, and it dominates because it is the one direct multiplication by tenant count with no economy of scale.
- Monitoring and alerting. Every isolated database is a distinct monitored target - CPU, disk, replication lag, slow queries. More targets means more dashboard noise and more alerts that turn out to be nothing, and someone has to triage that noise even on a quiet month.
The total, and what moves it
At 10,000 tenants, a month that includes one routine schema change costs roughly $30,600 in ops labor: ~$25,050 of migration supervision, ~$3,750 of backup triage, ~$1,200 of monitoring and ~$600 of pooler upkeep - before anyone looks at what the 10,000 database instances cost to host.
Sensitivity matters more than the headline number. Halve the assumed hourly rate to $75, and the 10,000-tenant ops labor is still roughly $15,300, more than most teams have budgeted for a single column addition. Halve the tenant count to 5,000 instead and migration supervision is still on the order of $12,500.
What actually protects you isn't a cheaper engineer. It's not choosing database-per-tenant at that scale in the first place - or building the tooling to run one migration unattended across every tenant database, which is itself an engineering project, not a free option.
Key takeaway
The database instance is rarely the expensive part of database-per-tenant. The expensive part is that every operation which would run once on a shared database has to run, and be watched, once per tenant.
Where this math stops applying
Three cases where the arithmetic above does not decide anything:
Compliance-driven isolation. When a contract or a regulator requires a tenant's data to sit in a physically or logically separate database - data residency terms, a healthcare or government deployment - the isolation is not a scaling choice you are weighing against cost. It is a term of the deal, and the ops cost above is simply what that term costs to deliver.
Low tenant counts. Under roughly 100 tenants, none of the columns above add up to more than a few hours a month. The pattern is not expensive yet; it becomes expensive when it grows, which is exactly when it is hardest to migrate away from.
Automated, unattended migration tooling. If a team has already built orchestration that runs a schema change across every tenant database without a human watching each one, the migration-supervision column collapses toward zero. That tooling is real engineering work with its own cost, so building it is a bet that you will run enough migrations across enough tenants for the investment to pay back - not a reason to treat the pattern as free.
Where BuildBase sits in this
BuildBase's workspaces module isolates each customer's data, feature
flags, members and billing by workspace rather than by database - the ceiling
is workspace count per plan (1,000 on Launch, 25,000 on Grow, 100,000 on
Scale, per PLANS in the platform constants, verified 9 September 2026), not a
connection limit per instance. A schema change runs once, against one
database, regardless of how many workspaces sit on top of it. That is a
different tradeoff than database-per-tenant, not a strictly better one - a
workspace does not get its own physically separate database, which is exactly
the property compliance-driven isolation above requires. If that property is
what you need, this math was never arguing against it. For the fuller version
of that tradeoff - a workspace-scoped SDK against a Postgres database you
provision and query yourself - see
Supabase vs BuildBase.
If you're counting per-tenant instances because what multi-tenancy costs in general is the real question, this post is the narrower, working-code version of it.