# Multi-Tenant SaaS Architecture Pre-Launch Checklist

> A production-ready checklist covering tenant isolation, data security, observability, and scaling concerns before launching a multi-tenant SaaS product.

- **Published:** 2025-03-15
- **Author:** Clixo
- **Reading time:** 6 min read
- **Tags:** multi-tenant, saas-architecture, checklist, pre-launch, tenant-isolation
- **Canonical URL:** https://clixo.sh/blog/multi-tenant-saas-architecture-pre-launch-checklist

Launching a multi-tenant SaaS with a structural flaw in the isolation or scaling layer means you will discover the problem under pressure — when a customer reports a data leak, when a noisy tenant takes down your application at peak load, or when an enterprise audit reveals you cannot demonstrate physical data separation. These failures are expensive in the ways that matter most: trust, revenue, and engineering time.

This checklist covers the architecture decisions and implementation details that should be verified before you accept your first paying tenant.

```mermaid
flowchart LR
  A[Data Isolation] --> GATE{Launch gate}
  B["Auth and AuthZ"] --> GATE
  C["Tenant Provisioning"] --> GATE
  D["Rate Limiting"] --> GATE
  E["Observability"] --> GATE
  F["Security Review"] --> GATE
  GATE -- all pass --> G[Launch]
  GATE -- gaps found --> H[Fix and retry]
  H --> GATE
```

## Data Isolation

- [ ] **Database isolation model is documented.** You have an explicit architecture decision record (shared schema with RLS, schema-per-tenant, or database-per-tenant) with rationale tied to your current tenant count and compliance requirements.
- [ ] **Every tenant-scoped table has a `tenant_id` column or schema namespace.** No exceptions. Audit the schema and confirm there are no orphaned tables that lack tenant attribution.
- [ ] **Row-level security (if shared schema) is enabled with FORCE.** `FORCE ROW LEVEL SECURITY` is set on all tenant-scoped tables to ensure table owner roles are also subject to policies.
- [ ] **RLS policies are tested with automated cross-tenant access tests.** A test suite asserts that tenant A cannot read or write tenant B's rows, with and without explicit `WHERE tenant_id` filters.
- [ ] **`WITH CHECK` policies are defined for write operations.** INSERT and UPDATE operations are blocked for rows that do not match the current tenant context.
- [ ] **Admin and migration roles are documented and access-controlled.** Roles with `BYPASSRLS` or schema-level permissions are explicitly listed and never used by the application process.

## Multi-Tenant Authentication and Authorization

- [ ] **Tenant context is resolved from the identity token, not from request parameters.** The `tenantId` in the JWT claim or session is the authoritative source. User-supplied tenant IDs in query strings or request bodies are rejected.
- [ ] **Authorization checks validate both role and tenant membership.** A user who is admin in tenant A cannot perform admin actions in tenant B.
- [ ] **Service-to-service calls propagate tenant context.** Internal services verify the tenant claim before processing requests.
- [ ] **Tenant context is immutable for the lifetime of a request.** Middleware sets it once; no downstream code overwrites it.

## Tenant Provisioning

- [ ] **Tenant provisioning is fully automated.** No manual steps are required to create a new tenant. The provisioning script is version-controlled and tested.
- [ ] **Provisioning is idempotent.** Running the provisioning script twice for the same tenant produces the same result without creating duplicate records or orphaned resources.
- [ ] **Provisioning is covered by integration tests.** The provisioning path is exercised in CI, not only verified manually before launch.
- [ ] **Tenant deletion / data export path is implemented and tested.** The path for GDPR deletion requests and tenant offboarding exists and has been exercised in a non-production environment.

## Per-Tenant Configuration

- [ ] **Feature flags are stored and resolved per tenant.** The system supports enabling and disabling features independently per tenant, not only per deployment.
- [ ] **Plan limits are enforced per tenant.** Rate limits, seat counts, API quotas, and storage caps are configurable per tenant and enforced at the API and application layers.
- [ ] **Configuration changes propagate without redeployment.** Changing a tenant's feature flag or plan limit takes effect without requiring a code deployment.

## Rate Limiting and Resource Isolation

- [ ] **Per-tenant rate limits are implemented at the API layer.** Rate limits are tiered by plan. Responses include `Retry-After` headers.
- [ ] **Background job queues have per-tenant concurrency limits.** High-volume, low-priority jobs cannot starve time-sensitive jobs from other tenants.
- [ ] **Database connection pools have per-tenant limits (if applicable).** A single tenant cannot exhaust the shared connection pool.
- [ ] **Statement timeouts are set for application database roles.** Long-running queries that exceed the timeout are terminated automatically.

## Multi-Tenant Observability

- [ ] **Every log line, metric, and trace is tagged with `tenant_id`.** Aggregate metrics can be broken down by tenant.
- [ ] **Per-tenant dashboards exist.** You can view request rate, latency, and error rate for any individual tenant.
- [ ] **Alerts fire on per-tenant anomalies.** High error rate or latency spikes for a single tenant trigger an alert without requiring the aggregate metric to cross a threshold.
- [ ] **Distributed traces carry tenant context.** You can retrieve all traces for a given tenant during a specific time window.

## Security and Compliance

- [ ] **Secrets are not shared across tenants.** API keys, encryption keys, and credentials are scoped per tenant where applicable.
- [ ] **Data at rest encryption is in place.** Encryption is enabled at the storage layer. Per-tenant encryption keys are considered if your compliance posture requires them.
- [ ] **Audit log captures tenant context.** Security-relevant actions (login, data export, permission change) are logged with `tenant_id`, `user_id`, and timestamp.
- [ ] **Penetration test or security review has covered cross-tenant access vectors.** This is not optional before accepting enterprise customers.

## Scaling

- [ ] **You have defined the tenant count and data volume you are designing for.** Architecture decisions are made against concrete projections, not vague "we'll scale later."
- [ ] **Database indexes exist on `tenant_id` columns.** All tenant-scoped tables have an index on `tenant_id`. Hot query patterns have composite indexes.
- [ ] **You have a documented path for migrating tenants to a higher isolation tier.** When an enterprise customer requires schema-per-tenant or database-per-tenant isolation, the migration path exists in writing even if the automation does not yet exist.

No checklist eliminates architectural risk, but working through it before launch surfaces the assumptions and gaps that would otherwise become incidents. The cost of addressing them pre-launch is a fraction of the cost of addressing them post-incident.

If you want a second set of eyes on your multi-tenant architecture before launch, [talk to Clixo](https://clixo.sh/#contact).

---

Clixo · 1141 W Bryn Mawr Ave, Itasca, IL 60143, US · [hello@clixo.sh](mailto:hello@clixo.sh)
[Start a build](https://clixo.sh/#contact) · [All services](https://clixo.sh/services) · [Agent guide (llms.txt)](https://clixo.sh/llms.txt)
