You’re building a SaaS product. You’ve got product-market fit signals, a handful of paying customers, and enough runway to ship something serious. Then someone on Slack asks: “Are we going multi-tenant from day one?”
That question-seemingly technical-will shape your entire business. Get it wrong and you’ll either haemorrhage money on infrastructure you don’t need, or hit a brick wall when you try to scale. Worse: some of these decisions are nearly impossible to reverse without a complete rewrite.
This is what we see repeatedly. Founders make architectural choices based on what they think they should do, not what their business actually needs right now.
Single-Tenant vs Multi-Tenant: The Irreversible Fork
Let’s be clear about what these mean. Single-tenant means each customer gets their own database, server infrastructure, and typically their own deployment. Multi-tenant means multiple customers share the same infrastructure but their data is logically or physically separated.
Single-tenant is simpler to build initially. Your first customer gets their own Postgres database, their own API server, maybe their own Redis cache. You deploy with a git push. No complex logic to filter data by tenant ID. No questions about whether one customer can accidentally see another’s data.
The catch: you’ll spend 40-60% of your engineering effort on DevOps and infrastructure management. Every new customer means a new deployment pipeline to maintain, backups to manage, upgrades to coordinate. A fintech product we worked with started single-tenant. By customer twelve, they had a part-time ops person managing deployments. By customer thirty, they needed a full engineer dedicated to infrastructure. They eventually rebuilt as multi-tenant-a three-month detour that cost them six figures in lost development velocity.
Multi-tenant is harder initially but scales your business, not your ops overhead. One database. One code deployment. Data isolation handled in application logic (or via row-level security in Postgres). When you add customer fifty, nothing changes operationally.
The decision should hinge on this: will you have 10+ paying customers in the next 18 months? If yes, multi-tenant now saves you rebuilding later. If no, single-tenant buys you speed and simplicity.
Database Strategy: This Cannot Be Changed Painlessly
Once you pick your tenant isolation approach at the database layer, changing it is a nightmare. You’ll be re-architecting queries, migrations, and security rules.
You have roughly three paths for multi-tenant databases:
- Shared database, shared schema: One table for all tenants with a
tenant_idcolumn. Simple to build. Queries are fast if you index properly. But: one bug in your filtering logic and tenant A sees tenant B’s data. You must enforce tenant_id checks everywhere-in queries, APIs, background jobs. It’s error-prone because the mistake is often invisible until audit logs reveal it. - Shared database, separate schemas: One Postgres instance, separate schema per tenant. Better isolation-a bad query can only see that tenant’s data. But schemas multiply: 100 customers = 100 schemas to manage. Schema migrations become complex. Tools like Supabase handle this, but you’re betting on their tooling staying stable.
- Separate databases per tenant: Each customer gets their own database. Maximum isolation. Easier to comply with data residency laws (important for European or regulated customers). Cost multiplies though: database hosting, backups, monitoring. You’re back to managing dozens of databases. Hybrid approach: separate databases for large customers, shared multi-tenant database for small ones. This works but requires two code paths.
Most early-stage SaaS should start with shared database, shared schema with strict filtering. It’s the fastest to ship and scales to 100+ customers with discipline. Only migrate if you hit specific scaling walls or compliance requirements.
Billing and Metering: Bake It In Now
Your tenant isolation architecture must sit on top of a billing foundation you’ve thought through. This is where we see the most regret.
Here’s the pattern: you launch with a simple per-seat model (AUD 99/month per user). Six months in, a customer wants to pay per API call. Another wants a usage-based tier. You retrofit metering onto code that was never designed to track it. Now every feature request requires changes to billing logic.
Build from day one with this approach:
- Decide: will you charge per seat, per feature, per usage, or hybrid?
- Log every billable event to an immutable events table (user created, API call made, report generated)
- Build a metering service that reads those events, aggregates them, and computes usage
- Keep billing calculations separate from feature code-never embed pricing logic in your product features
- Plan for at least three pricing tiers from launch, even if two are disabled initially
The cost of adding this later-separate engineers, rewriting code that spans your codebase, customer confusion during migration-typically runs AUD 50k-150k and six weeks of calendar time. Build it in week one and it costs a few thousand and three days.
Authentication and Security: Tenant Context Everywhere
Once you’re multi-tenant, every request must carry its tenant context through your entire stack. Get this architecture wrong and you introduce subtle security bugs that live undetected for months.
The pattern that works:
- User logs in, JWT token includes their tenant_id and user_id
- Every API request extracts tenant_id from the token and passes it to your service layer
- Database queries automatically filter by that tenant_id (via Postgres row-level security, or application-level filtering that cannot be bypassed)
- Background jobs, webhooks, and async tasks re-validate tenant context before processing
The mistake: burying tenant context deep in your codebase as a “context” variable that gets set somewhere in middleware. Then one engineer forgets to check it in a new endpoint. Six months later, audit reveals customer A downloaded customer B’s report.
Make tenant isolation so explicit it’s boring. Every function that touches data should have tenant_id as a required parameter. Yes, it’s verbose. That verbosity is a feature-it makes mistakes obvious.
What to Decide Now, What to Defer
Not everything is permanent. But these are the three architectural bets you should lock in before your first paying customer:
- Single vs multi-tenant infrastructure – Defer this only if you’re genuinely uncertain you’ll have 10+ customers. Otherwise decide now.
- Tenant isolation strategy at the database layer – Pick one and commit. Changing it is a full rewrite.
- Billing event tracking and metering foundation – You don’t need fancy pricing tiers yet. But the pipes to measure and bill usage must exist.
Everything else-API design, frontend framework, queue system, caching layer-you can iterate or change. Those three? You’ll live with them for years.
If you’re building a B2B SaaS product and unsure where to land on these decisions, talk to Amora about your build. We’ve shipped enough MVPs that these questions have clear answers for your specific situation.
Ship fast, but ship with a foundation that won’t collapse when you succeed.
Got something you want built?
Amora Digital is an Australian software and AI agency. We scope it, build it, and ship it – live in 28 days. No offshore teams. No surprises.