SaaS

Architecting Multi-Tenant SaaS Systems For Scale & Security

Key design patterns for database isolation, role-based access control (RBAC), and subscription metering in modern web software.

AW

Alexander Wright

Managing Director & CEO

6 min read
Architecting Multi-Tenant SaaS Systems For Scale & Security

Key Takeaways

  • Choose a tenancy model early; it shapes cost, security and migration effort.
  • Enforce tenant isolation in the data layer, not only in application code.
  • Model roles and permissions separately from users for flexible RBAC.
  • Meter usage at the event level so billing stays accurate as you scale.

Multi-tenancy lets one application serve many customers while keeping their data separate. Done well, it lowers infrastructure cost and speeds up releases. Done poorly, it creates data leaks and painful migrations. These are the decisions that matter most.

Choosing a Tenancy Model

There are three common approaches, each balancing isolation against cost and operational complexity.

  • Shared database, shared schema: every row carries a tenant identifier. Cheapest and simplest to scale, but isolation relies on discipline.
  • Shared database, separate schemas: stronger separation with moderate overhead, useful for mid-sized customers.
  • Separate database per tenant: maximum isolation and easy per-customer backup, at higher cost and operational load.

Rule of thumb

Start with a shared schema and a tenant_id on every table, and design so that high-value enterprise tenants can later be moved to dedicated databases.

Enforcing Tenant Isolation

Never trust every query to remember the tenant filter. Push enforcement down into the database with row-level security or a data-access layer that injects the tenant context automatically. Add automated tests that attempt cross-tenant reads and must fail.

sql
-- PostgreSQL row-level security example
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON projects
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

Role-Based Access Control

Keep users, roles and permissions as separate concepts. Users hold roles within a tenant, roles bundle permissions, and permissions describe actions on resources. This makes it simple to add custom roles for enterprise customers without changing code.

  1. 1Define permissions as verbs on resources, such as invoice.read or member.invite.
  2. 2Group permissions into roles like Owner, Admin, Member and Viewer.
  3. 3Scope role assignments to a tenant so one user can have different roles in different organizations.
  4. 4Check permissions on the server for every sensitive action.

Subscription Metering and Billing

Usage-based pricing needs trustworthy numbers. Record usage as immutable events, aggregate them per billing period, and sync totals to your payment provider. Keep plan limits in configuration so product and sales teams can adjust packages without a deploy.

“If you cannot explain an invoice line from raw events, your metering is not finished.”

— Alexander Wright, FidayinCorporate

Scaling and Observability

Watch for noisy neighbours: one heavy tenant slowing everyone else. Add per-tenant rate limits, query timeouts and dashboards that break metrics down by tenant. These signals tell you when it is time to shard or move a customer to dedicated resources.

TagsSaaSMulti-TenancyRBACBilling
Share
AW

Written By

Alexander Wright

Managing Director & CEO

12+ years leading enterprise digital transformations and cloud architecture strategies.