All insights

Multi-Tenant SaaS Architecture: Lessons from Real Platforms

Multi-tenancy looks simple until the first customer asks for their own domain, branding and backups. These are the architecture decisions that matter most before you write code.

By Amir Nassar4 min read
Table of contents

A multi-tenant application serves many customers from one codebase, with each customer seeing only their own data and their own branding. Since 2022 we have built several platforms this way, including a venue management SaaS and an Arabic learning platform where every teaching center runs its own branded site. This article collects the decisions that shaped those projects and that we would make again.

Decide the tenancy model first

There are three common ways to separate tenants, and the choice affects almost everything that follows.

  • Shared database, shared tables. Every row carries a tenant identifier. It is the cheapest to run and the easiest to migrate, but a missed filter can leak data between customers.
  • Shared database, separate schemas. Better isolation, with more operational work when you have hundreds of tenants.
  • Separate database per tenant. The strongest isolation and the simplest per-customer backup and restore, at the cost of running migrations many times and monitoring many connections.

For most early-stage SaaS products the shared-table model is the pragmatic start. Move to separate databases when a customer contractually requires isolation, or when tenant sizes vary so much that one noisy customer slows everyone else.

Make tenant scoping impossible to forget

The most serious multi-tenant bug is a query that forgets the tenant filter. Do not rely on every developer remembering it. In Laravel, a global scope applied through a trait on every tenant-owned model makes the filter automatic, and a base model class makes it hard to opt out by accident.

Test isolation explicitly

Write feature tests that create two tenants, sign in as a user of the first, and assert that records of the second never appear in lists, searches, exports or API responses. These tests are cheap, and they catch the mistakes that otherwise surface as a customer complaint.

Remember the places scopes do not reach

Raw queries, reports, cached values, file storage paths and queued jobs all bypass model scopes. Prefix cache keys and storage directories with the tenant, and pass the tenant identifier into every job so it runs in the right context.

Branding and domains are product features

Customers of a white-label platform expect their own logo, colours and often their own domain. Treat these as data, not code: store the theme settings per tenant, resolve the tenant from the incoming host, and keep a fallback subdomain for customers who have not yet pointed a domain at you. Plan for certificates early, because custom domains need automated HTTPS issuance and renewal.

In our Multi-Tenant Arabic Learning Platform, each teaching center or academy runs its own branded platform with protected video, online payments and assessments. In VnuMngr, each venue gets a branded website with built-in booking next to the management dashboard. In both cases the lesson was the same: the tenant settings screen is a core part of the product, not an afterthought.

Billing, limits and plans

Decide early how plans map to features. Store plan limits as data, check them in one place, and avoid scattering plan names through the code. When you later add a tier, you want to change a configuration record, not search for every conditional.

Operations at scale

Queues and fairness

Background jobs such as email, exports and imports can let one large tenant starve the others. Use separate queues for heavy work, and set sensible timeouts and retry limits so a single failing job does not block the rest.

Migrations and releases

With a single database, migrations are simple. With a database per tenant, make migrations idempotent, run them in batches, and decide what happens when one tenant fails halfway. Keep deployments backward compatible for a release or two, so the application and the schema do not have to change at the exact same moment.

Backups and data export

Customers will eventually ask for their data. Design a per-tenant export from the start, and test restoring a single tenant from backup before you need to do it under pressure.

A short pre-build checklist

  1. Which tenancy model fits our isolation and cost needs today, and what triggers a move to the next one?
  2. Where is the tenant resolved: subdomain, custom domain, or path?
  3. How do global scopes, cache keys, storage paths and jobs carry the tenant?
  4. What is configurable per tenant: branding, language, features, limits?
  5. How do we export, back up and delete one tenant cleanly?

Getting these answers on paper before development starts saves weeks of rework later. If you are planning a SaaS product and want an architecture review, look at our services or talk to the Narmar team. We are happy to challenge your assumptions before they become code.

Share this article

Planning something similar?

Tell us about your project — we reply within one business day with next steps and an honest estimate.

Talk to our engineers

Get the next insight in your inbox

Practical notes on software, AI and ERP for growing businesses. No spam — unsubscribe in one click.