One codebase, many clients,
each one unable to see another's data
A SaaS product running multiple clients on one codebase has to get isolation right the first time. The failure mode is one client seeing another's data, not a bug you discover slowly. We build the tenant boundary into the data layer itself, not just the application logic on top of it. We design per-tenant configuration so onboarding a client is a database row, not a deployment.
What isolation actually means here
Multi-tenant architecture lets one application and one codebase serve many separate clients, tenants, while keeping each tenant’s data, configuration and usage completely isolated from every other. The hard part is not the feature work. It is making sure a bug or a misconfigured query cannot leak one tenant’s data into another’s view. That is why isolation needs enforcement at the data layer, with row-level security or an equivalent mechanism. It cannot be left to application code remembering to filter by tenant on every single query.
When you actually need this
You need this when you are building a SaaS product meant to serve many clients from one platform. You also need it when you already run separate instances per client. The operational cost of that, one deployment, one database, one set of updates per client, has become unmanageable. It is the right architecture once you expect enough clients that provisioning a new one by hand, a new server, a new database, does not scale.
You do not need multi-tenancy for an internal tool used by one organization, or for an early-stage product still finding its first few clients. A single-tenant build is simpler to reason about and faster to ship there. Multi-tenancy adds real complexity that is only worth paying for once the number of clients, or the cost of managing separate instances, justifies it.
How we build it
For most products, we use a shared database with enforced row-level isolation in PostgreSQL. Every table that holds tenant data carries a tenant identifier. Database-level policies, not just application code, reject any query that does not properly scope to the right tenant. Even a mistake in application logic cannot leak data across the boundary this way. Per-tenant configuration, branding, feature flags, usage limits, lives in its own table and gets read at request time. Turning on a feature for one client, or adjusting their limits, becomes a data change, not a code deployment.
Onboarding a new tenant becomes a provisioning flow: create the tenant record, set initial configuration, and the application is ready for that client without touching infrastructure. Monitoring and logging are tagged by tenant. A performance problem or an error spike traces back to the client actually causing it, rather than looking like a platform-wide issue. Where a specific client’s regulatory requirements genuinely demand stronger separation than row-level isolation provides, we scope a dedicated schema or database for that tenant. We do not over-engineer isolation for every client by default.
What to watch
Shared-database multi-tenancy means a single database outage affects every tenant at once. That is a real trade-off against the operational simplicity it buys. Backup and disaster recovery planning matters more here, not less. Schema changes need to account for every tenant’s data at once, so we plan migrations with that in mind rather than treating them as routine. The row-level isolation policy is the single most security-critical piece of the system. That is why we test it explicitly, instead of just trusting that application code filters correctly.
Price and timeline
| Option | Price | What it covers | Timeline |
|---|---|---|---|
| MVP | from $4,000 | Shared-database isolation, basic per-tenant configuration, provisioning flow | 4 to 8 weeks |
| Production | from $9,000 | Full configuration layer, per-tenant monitoring, billing hooks, migration from existing instances | 8 to 14 weeks |
Related
This pairs with role-based access control and audit log and compliance trail for the access layer inside each tenant. It also pairs with backup and disaster recovery, given the shared-database trade-off. It is part of the development service. The multi-brand isolation pattern here is close to the analytics hub serving two brands and the platform architecture behind the ProBay AI agent team.
Ready to move off one instance per client? Get in touch and describe how many clients you expect to onboard.
FAQ
How much does multi-tenant architecture cost?
From $4,000 for a standard shared-database design with row-level isolation for a straightforward SaaS product. More complex per-tenant customization or a migration from separate instances costs more.
How long does it take?
4 to 8 weeks. It depends on how much of the application already exists and needs retrofitting, versus being built tenant-aware from the start.
Shared database or separate databases per client?
We default to a shared database with enforced row-level isolation. It scales well and keeps operational cost down for most SaaS products. A handful of clients needing strict regulatory separation can justify dedicated schemas or databases instead, which we scope specifically.
Who owns the architecture and the code?
You. The system runs on your infrastructure, in your repository, from the first commit.
What happens if we already have separate instances per client today?
We plan a migration path that moves clients onto the shared platform gradually, verifying isolation at each step, rather than a single risky cutover.