Tenant Hosting
Tenant data hosting options including dedicated databases, shared databases, and isolation strategies
MQUAD supports multiple tenant data isolation strategies to meet different compliance and scalability requirements.
Isolation Strategies
| Strategy | Isolation | Cost | Complexity | Use Case |
|---|---|---|---|---|
| Shared Database | Row-level | Low | Low | Small tenants, SaaS |
| Schema-per-Tenant | Schema-level | Medium | Medium | Medium tenants |
| Database-per-Tenant | Database-level | High | High | Enterprise, compliance |
Shared Database (Default)
All tenant data resides in the same database, isolated by tenant_id column:
# Every query filters by tenant_id
query = select(Survey).where(Survey.tenant_id == request.state.tenant_id)Pros: Simple, low overhead, easy to manage.
Cons: No hard isolation boundary.
Database-per-Tenant
For maximum isolation, each tenant gets dedicated databases:
async def _create_tenant_databases_for_services(self, tenant_id: str):
services = ["survey_db", "data_db", "workspace_db", ...]
for base_db in services:
tenant_db = f"{base_db}_tenant_{tenant_id.replace('-', '_')}"
# CREATE DATABASE tenant_db
# Run migrations on tenant_db
# Register in tenant_metadataNaming Convention
{base_db}_tenant_{tenant_id_underscored}Example: survey_db_tenant_acme_org
Tenant Creation Flow
- Create tenant record in
appdb.tenants - Seed tenant roles (Admin, Editor, Viewer)
- Create tenant databases across all services
- Run Alembic migrations on each tenant database
- Create admin user for tenant
Configuration
Tenant isolation mode is configured via environment variables:
TENANCY_ENABLED=true
TENANT_DB_ISOLATION=database # shared | databaseFrontend Routing
// Dashboard layout routes by tenant status
if (isDormant && isAdmin) -> /dormant-admin
if (isDormant && !isAdmin) -> /tenant-offline
if (!is_active) -> /non-active