In short
Pick the simplest way to separate customers that your contracts allow, and enforce it somewhere no developer can skip. Then plan for everything else tenancy touches, from domains and files to billing and deleting an account. Add infrastructure only when a real reason demands it.
On this page
A multi-tenant SaaS serves many customers from one product, while each of them feels like it's theirs alone. It's how most software you pay for monthly works, and it's the decision that shapes your product the most.
I build and run a multi-tenant platform used by 10+ paying businesses. This is the guide I'd give a founder starting one today: what to decide first, what catches people out, and what can safely wait.
Choose how customers are kept apart
There are three common ways to separate customers' data:
| Approach | Isolation | Running cost | Good for |
|---|---|---|---|
| Shared tables with a tenant ID | Enforced by your code | Lowest | Most new products |
| A schema per tenant | Stronger | Medium | Fewer, larger customers |
| A database per tenant | Strongest | Highest | Strict compliance or data-location contracts |
Each step down the table buys stronger separation and costs more to run, migrate and report across. Start with the simplest option your customers' contracts allow. Moving to separate databases later is real work, but it's work you'll only need if those customers turn up.
Not sure which one fits? Answer these and I'll tell you where I'd start.
Decision tool
How should you separate your customers' data?
Four questions to find a sensible starting point.
1How many customers do you expect in a year?
2Do customers need their data kept physically apart?
3Do customers need custom fields or their own data shape?
4Who runs this day to day?
Your answer
Questions left until I can tell you what I'd pick: 4
Make the boundary impossible to forget
Whichever you choose, the biggest risk in a multi-tenant product is one customer seeing another's data. It usually happens through one forgotten filter, not a clever attack.
- Scope every query in one place, where a developer can't skip it, rather than trusting everyone to remember.
- Add a second layer. Database features like row-level security keep working even when application code has a bug.
- Test the line on purpose. Write tests that sign in as one customer and try to read, change and delete another's data. They should fail loudly.
- Check it in review. Any new table, cache or file path should answer one question: whose is this?
Tenancy is more than a database
The database gets the attention, but these take more of the time:
- Domains. Customers want their own address. That means routing by hostname, issuing certificates and handling DNS that's set up wrong.
- Branding. If your product is white-label, every email, sign-in page and error message has to carry the customer's brand, not yours.
- Files, caches and queues. A cache key or file path without the customer in it is the same bug as a query without a filter.
- Features per customer. Different customers need different things. Plan how features are switched on and off before you hard-code them.
- Billing. Plans, trials, upgrades, failed payments and currencies all belong to the customer, not the user.
- Languages. Right-to-left support, like Arabic, is far cheaper to plan early than to add later.
- Leaving. Customers will ask to export their data and to have it deleted, backups included. Decide how before the first one asks.
Keep the infrastructure simple
Early on, every extra moving part is one more thing to understand, monitor and fix at night. A simple setup keeps costs predictable and failures easy to find. Simple doesn't mean careless, though. These aren't optional at any size:
- Backups you've actually restored. A backup you've never restored is a hope, not a backup.
- Deploys that don't take customers down. One customer's change shouldn't disturb everyone else.
- Limits on everything. One busy customer shouldn't slow everyone else down.
- Monitoring from outside. A system can't always tell you it's down.
- A written recovery plan. Know how you'd rebuild before you need to.
When to add complexity
Add infrastructure for a concrete reason, not on principle:
- You've promised an uptime your setup can't honestly meet.
- A customer's contract requires separation or a specific region.
- You've measured a limit you can't solve with a better query or a bigger machine.
"We might get big" isn't on that list. Plenty of products never need more, and the ones that do will have the revenue to pay for it.
Before you launch
- Every query, cache key and file path carries the customer
- Tests try to cross between customers, and fail
- Backups restored at least once
- A customer can export their data and have it deleted
- Billing handles failed payments and cancellations
- Someone gets alerted when the site is down
Spend your early effort on the product and on keeping customers apart, and keep the rest simple. Customers don't care how your system is arranged. They care that their site is up, their data is safe and they can change a price without emailing anyone.
If you're planning a SaaS and want to talk it through, that's the kind of work I take on.
Written by Khaled Jamal
Software engineer in Beirut, known online as Dequavious, and founder of Helm. I build SaaS platforms, AI agents, desktop apps and client sites end to end.






