In this article
Trace a tenant beyond the first HTTP request
Imagine two organisations using a shared booking product. Both can have a booking numbered 42. A cache keyed only by booking number may return one organisation’s data to the other, even when the database queries are correct. The same risk appears in file paths, search indexes, export jobs and background notifications.
Derive tenant identity from the authenticated membership and validate the selected organisation server-side. Carry that context into asynchronous work; a worker does not inherit the browser session. Scope resource identifiers and cache entries accordingly. When an administrator switches organisations, make the change visible in the interface and re-check membership. A tenant field supplied by the browser is a request to validate, not authority to access the tenant.
Tenant identity travels with the request
Isolation must hold throughout the workflow, including background jobs.
Identity
Authenticate the caller and resolve their organisation.
Authorisation
Check the operation and the target record.
Data boundary
Apply the chosen isolation model consistently.
Async work
Carry the same context into jobs, exports and logs.
Treat tenancy as a system invariant
A tenant is not just a foreign key. It defines who can act, which configuration applies, how data is isolated, how usage is measured and what must happen during suspension, export or deletion.
Choose a canonical tenant context at authentication and carry it through commands, queries, background jobs, caches, files and telemetry. Missing context should fail closed rather than fall back to a default tenant.
Choose isolation from consequence and operations
Shared tables are operationally efficient but require pervasive row isolation and tests. Separate schemas or databases increase isolation and migration complexity. The choice depends on sensitivity, noisy-neighbour risk, restore granularity and the team’s operating capacity.
Document where configuration, secrets and encryption keys live. A mixed model may isolate only regulated or high-volume tenants, but it needs one routing contract and consistent lifecycle automation.
Design lifecycle and recovery before billing
Provisioning, invitations, role changes, plan transitions, limits, suspension and deletion must be idempotent workflows. Billing state must not silently become authorization state without a documented grace and recovery policy.
Observe usage and failures by tenant without exposing personal data. Rehearse export and restore for one tenant, and test that a failed migration cannot leave half the tenant fleet on incompatible schemas.
Choose isolation with a recovery scenario
Shared tables can simplify operations, while separate schemas or databases can make some isolation and restoration tasks easier at the cost of more migrations, connections and monitoring. Neither topology removes the need for application authorisation. Compare what happens when one tenant needs a data export, an individual restore or a different retention policy.
PostgreSQL row-level security can restrict rows accessible to a database role, but owners and privileged roles have important bypass behaviour. Test with the actual runtime role, not only with an administrator account. If connection pooling carries request context, verify that it is reset between requests. Database policy should reinforce the application boundary, with tests that deliberately attempt cross-tenant reads and writes.
Isolation is also an operating choice
Qualitative trade-offs to test against your workload. All options still need authorisation.
Scroll horizontally to read the table →
| Topology | Operating advantage | Work to plan |
|---|---|---|
| Shared tables | Fewer databases to operate | Tenant-scoped queries, caches and restore strategy |
| Schema per tenant | Logical separation of tenant structures | Migration coordination and connection context |
| Database per tenant | Separate backup and resource boundaries | Fleet migrations, credentials and monitoring |
Exercise the complete tenant lifecycle
Provisioning should be repeatable after interruption: creating the organisation, its initial administrator and default configuration must not leave an invisible half-created account. Suspension should stop the intended actions without destroying the information needed for support. Deletion needs a defined treatment for search indexes, exports, files and backups, not just the primary database rows.
Test noisy-neighbour behaviour too. A large import for one customer should not silently exhaust every worker or block small interactive requests. Track queue age and resource use by tenant where practical, then choose fair scheduling or quotas according to the product’s needs. The resulting architecture should explain both confidentiality and service quality for each organisation, including during incidents.
Sources & further reading
Documentation consulted on .
FAQ / DECISIONS
Frequently asked questions
Should every tenant have its own database?+
No. Use separate databases when isolation, scale, contractual or restore requirements justify the added routing and operational work.