Focus mode active/Press Alt+Shift+R to toggle/Esc to exit
Deepen PracticeOrdered learning track

Multi-Tenancy, Tenant Isolation, and Deployment Topology Model

Model multi-tenancy, tenant isolation, customer boundary, environment boundary, deployment topology, cloud/on-prem separation, data residency, tenant-scoped identifiers, tenant-aware indexing, tenant-aware events, and production correctness untuk enterprise CPQ/Quote/Order/Billing systems.

11 min read2052 words
PrevNext
Lesson 6182 lesson track46–68 Deepen Practice
#enterprise-data-modelling#multi-tenancy#tenant-isolation#deployment-topology+6 more

Multi-Tenancy, Tenant Isolation, and Deployment Topology Model

1. Core Idea

Enterprise data model harus menjawab pertanyaan:

Data ini milik tenant/customer/deployment/environment mana, dan boundary apa yang tidak boleh dilanggar?

Dalam enterprise SaaS, telco BSS/OSS, CPQ, quote/order/billing, satu platform bisa melayani banyak customer, region, deployment model, dan environment.

Deployment bisa berupa:

  • shared SaaS,
  • dedicated SaaS,
  • private cloud,
  • on-prem,
  • hybrid,
  • region-specific deployment,
  • customer-specific instance,
  • multi-environment setup: dev, test, staging, prod, DR.

Mental model:

Multi-tenancy is not only infrastructure. It must be encoded in identity, keys, indexes, events, caches, search, read models, audit, and access control.


2. Why Tenant Isolation Matters

Jika tenant isolation tidak jelas:

  • customer A bisa melihat quote customer B,
  • cache key menampilkan pricing tenant lain,
  • search index leak data antar tenant,
  • event consumer memproses event tenant yang salah,
  • batch job update data semua tenant,
  • report mencampur revenue tenant,
  • purge/anonymization tenant A menghapus data tenant B,
  • on-prem customer menerima config SaaS,
  • data residency dilanggar,
  • support user mengakses environment salah,
  • integration endpoint salah tenant.

Tenant isolation adalah salah satu boundary paling kritikal dalam enterprise production system.


3. Tenant vs Customer vs Account vs Organization

Jangan menyamakan tenant dengan customer.

ConceptMeaning
TenantRuntime/data isolation boundary.
CustomerBusiness party buying/using service.
AccountCommercial/operational relationship container.
OrganizationEnterprise hierarchy/legal entity.
DeploymentPhysical/logical runtime installation.
EnvironmentProd/staging/dev/test/DR boundary.
RegionGeographic/legal/latency boundary.

Example:

Tenant:
  csg-customer-prod-001

Customer inside tenant:
  GlobalCorp

Accounts inside customer:
  GlobalCorp APAC
  GlobalCorp Indonesia

Deployment:
  dedicated cloud deployment in APAC region

A tenant may contain many business customers in B2B2X scenarios. Or one customer may have a dedicated tenant.

Verify internal semantics.


4. Tenancy Models

Common models:

ModelDescription
Single tenantOne customer/deployment per application/database.
Shared database, shared schemaRows separated by tenant_id.
Shared database, separate schemaOne schema per tenant.
Database per tenantStrong isolation, higher operational complexity.
Deployment per tenantDedicated app/runtime/database.
HybridLarge customers dedicated, smaller shared.

Each model affects:

  • data model,
  • key strategy,
  • query filters,
  • migrations,
  • backup/restore,
  • reporting,
  • event routing,
  • tenant provisioning,
  • incident blast radius,
  • data residency.

5. Tenant Entity

Tenant entity represents isolation boundary.

Fields:

tenant
- id
- tenant_code
- display_name
- tenant_type
- status
- deployment_id
- region_code
- data_residency_region
- isolation_model
- provisioned_at
- suspended_at
- decommissioned_at

Tenant lifecycle:

PROVISIONING
ACTIVE
SUSPENDED
MIGRATING
DECOMMISSIONING
DECOMMISSIONED

Tenant status should affect:

  • login/access,
  • quote/order creation,
  • integrations,
  • billing,
  • background jobs,
  • data exports.

6. Deployment Topology Model

Deployment describes runtime placement.

Fields:

deployment
- id
- deployment_code
- deployment_type
- cloud_provider
- region
- environment
- cluster_id
- database_cluster_id
- message_broker_cluster_id
- search_cluster_id
- status

Deployment type examples:

  • shared-saas,
  • dedicated-saas,
  • private-cloud,
  • on-prem,
  • disaster-recovery,
  • migration-shadow.

Data model may need to know deployment topology for:

  • integration endpoint routing,
  • data residency,
  • support access,
  • tenant provisioning,
  • backup/restore,
  • operational reporting,
  • incident blast radius.

7. Environment Boundary

Environment must be explicit.

Examples:

DEV
TEST
SIT
UAT
STAGING
PRODUCTION
DR
SANDBOX
CUSTOMER_TEST

Data should not cross environment boundary casually.

Fields:

environment
- environment_code
- environment_type
- production_like
- data_policy
- integration_policy

Common failure:

Production integration event consumed by staging service.

Include environment in:

  • event metadata,
  • integration endpoint,
  • tenant registry,
  • cache namespace,
  • search index name,
  • logs,
  • monitoring,
  • data export.

8. Tenant-Scoped Tables

If shared schema, every tenant-owned row needs tenant boundary.

Example:

create table quote (
  tenant_id uuid not null,
  id uuid not null,
  quote_number text not null,
  customer_id uuid not null,
  status text not null,
  created_at timestamptz not null,
  primary key (tenant_id, id)
);

Or:

id uuid primary key,
tenant_id uuid not null

with every query filtering tenant_id.

Important:

  • primary key strategy,
  • foreign key includes tenant_id where possible,
  • unique constraints are tenant-scoped,
  • indexes include tenant_id,
  • API authorization verifies tenant scope,
  • cache key includes tenant_id.

9. Tenant-Scoped Unique Constraints

Business numbers may be unique per tenant, not globally.

Example:

create unique index uq_quote_number_per_tenant
on quote (tenant_id, quote_number);

For shared DB:

create unique index uq_order_source_quote_per_tenant
on product_order (tenant_id, source_quote_id, source_quote_version)
where source_quote_id is not null;

If tenant_id is missing from unique key, one tenant can block another tenant's valid business number or source reference.


10. Tenant-Aware Indexing

Common query:

select *
from product_order
where tenant_id = :tenant_id
  and customer_id = :customer_id
  and status = :status
order by updated_at desc
limit 50;

Index:

create index idx_order_tenant_customer_status_updated
on product_order (tenant_id, customer_id, status, updated_at desc);

Tenant_id should usually be first for tenant-scoped queries in shared schema.

But verify actual query patterns and cardinality.


11. Tenant-Aware Events

Every event should carry tenant/environment where applicable.

Example:

{
  "eventId": "uuid",
  "eventType": "QuoteAccepted",
  "tenantId": "tenant-id",
  "environment": "PRODUCTION",
  "aggregateType": "QUOTE",
  "aggregateId": "quote-id",
  "correlationId": "corr-123"
}

Consumers should reject/ignore events outside their tenant/environment scope.

Topic/queue strategy may include:

  • shared topic with tenant_id in payload,
  • tenant-specific topic,
  • deployment-specific broker,
  • environment-specific broker.

Do not mix prod and non-prod event streams.


12. Tenant-Aware Cache

Cache key must include tenant and environment.

Bad:

quote:{quoteId}
catalog:offering:{offeringId}
permission:{userId}

Better:

prod:{tenantId}:quote:{quoteId}:v:{version}
prod:{tenantId}:catalog:offering:{offeringId}:v:{version}
prod:{tenantId}:permission:{userId}:v:{permissionVersion}

If catalog is globally shared, key should still reflect version and deployment scope if variations exist.

Failure mode:

Tenant A sees tenant B pricing because cache key lacks tenant_id.

13. Tenant-Aware Search Index

Search index must isolate tenant data.

Options:

StrategyNotes
Index per tenantStrong separation, many indexes.
Shared index with tenant filterSimpler, requires strict query filter.
Index per deployment/regionUseful for residency.
HybridDedicated index for large tenants.

Search document should include:

tenant_id
environment
access_scope
data_classification
source_version
indexed_at

Search query must filter tenant/scope server-side.

Do not rely on frontend to filter search results.


14. Tenant-Aware Reporting

Reporting questions:

  • report per tenant,
  • cross-tenant platform ops,
  • customer-specific analytics,
  • regional reporting,
  • deployment-level performance,
  • SaaS aggregate KPI.

Controls:

  • row-level security,
  • tenant-scoped datasets,
  • anonymized aggregate cross-tenant reporting,
  • access audit,
  • tenant-aware data lineage.

Cross-tenant analytics must be governed because it can expose customer confidential information.


15. Data Residency

Data residency constrains where data can be stored/processed.

Fields:

data_residency_region
allowed_processing_regions
allowed_backup_regions
allowed_support_regions
restricted_export

Data residency affects:

  • database location,
  • backup location,
  • search index,
  • logs,
  • analytics,
  • object storage,
  • support access,
  • integration endpoint,
  • DR region.

Do not assume only main database matters. Derived data stores also count.


16. Regionalization

Region may affect:

  • tax,
  • currency,
  • latency,
  • legal entity,
  • data residency,
  • serviceability,
  • product availability,
  • deployment,
  • integration endpoint,
  • support team.

Model:

tenant_region_assignment
- tenant_id
- region_code
- role = PRIMARY / DR / REPORTING / SUPPORT
- effective_from
- effective_to

If customer operates globally, business region and data residency region may differ.


17. Tenant Provisioning

Provisioning creates tenant runtime/data.

Provisioning steps:

  • create tenant record,
  • assign deployment/region,
  • configure identity provider,
  • create database/schema/namespace if needed,
  • configure integrations,
  • seed reference data,
  • publish catalog/price baseline,
  • create admin users,
  • configure backup/monitoring,
  • run smoke tests.

Model:

tenant_provisioning_request
- tenant_id
- status
- requested_by
- started_at
- completed_at
- failure_code

Tenant provisioning is a workflow, not manual checklist only.


18. Tenant Configuration

Tenant-specific config may include:

  • enabled modules,
  • product catalog scope,
  • pricing model,
  • currency defaults,
  • locale/timezone,
  • billing integration endpoint,
  • OSS endpoint,
  • workflow variant,
  • feature flags,
  • data retention policy,
  • custom field enablement,
  • API limits.

Model:

tenant_configuration
- tenant_id
- config_key
- config_value
- value_type
- effective_from
- effective_to
- source

Govern tenant config carefully. It can create hidden behavior differences.


19. Tenant Feature Flags

Feature flags can be tenant-scoped.

Fields:

tenant_feature_flag
- tenant_id
- feature_key
- status
- rollout_group
- effective_from
- effective_to
- reason_code

Failure modes:

  • feature enabled for wrong tenant,
  • old code path and new data model mismatch,
  • flag removed before migration complete,
  • reporting does not know feature state.

Feature flags should be included in migration/cutover governance.


20. On-Prem and Hybrid Considerations

On-prem deployments may differ:

  • customer controls infrastructure,
  • upgrade cadence slower,
  • integration endpoints local,
  • data export restricted,
  • telemetry limited,
  • support access constrained,
  • database version differs,
  • event broker differs,
  • backup/restore owned by customer,
  • schema migration window narrower.

Data model should avoid assuming central SaaS control if on-prem is supported.

Need store:

deployment_type = ON_PREM
upgrade_channel
supported_version
customer_operated
telemetry_policy

21. Tenant Migration

Tenant may migrate:

  • shared to dedicated,
  • one region to another,
  • on-prem to cloud,
  • old version to new version,
  • tenant split/merge,
  • database/schema move.

Model:

tenant_migration
- id
- tenant_id
- from_deployment_id
- to_deployment_id
- migration_type
- status
- started_at
- completed_at
- cutover_at
- rollback_strategy

Migration requires:

  • data export/import,
  • ID preservation,
  • event replay/bridge,
  • integration endpoint switch,
  • search/read model rebuild,
  • cache invalidation,
  • reporting continuity,
  • data residency validation.

22. Tenant Decommissioning

Decommissioning must follow retention/legal hold.

Steps:

  • suspend access,
  • stop integrations,
  • export/hand over data if contract requires,
  • archive required records,
  • purge/anonymize allowed data,
  • revoke users/secrets,
  • delete cache/search/read models,
  • stop scheduled jobs,
  • remove tenant from routing,
  • keep tombstone/audit.

Model:

tenant_decommission_request
- tenant_id
- status
- retention_policy_checked
- legal_hold_checked
- completed_at

23. Tenant-Aware Background Jobs

Batch jobs must be tenant-aware.

Examples:

  • quote expiry,
  • order reconciliation,
  • billing trigger,
  • data quality scan,
  • retention purge,
  • projection rebuild,
  • cache warmup.

Fields:

job_run
- tenant_id nullable
- deployment_id
- environment
- job_type
- status
- started_at
- completed_at

Avoid background job accidentally scanning/updating all tenants without explicit scope.


24. PostgreSQL Physical Design

Tenant table:

create table tenant (
  id uuid primary key,
  tenant_code text not null unique,
  display_name text not null,
  tenant_type text not null,
  status text not null,
  deployment_id uuid,
  region_code text,
  data_residency_region text,
  isolation_model text,
  provisioned_at timestamptz,
  suspended_at timestamptz,
  decommissioned_at timestamptz,
  created_at timestamptz not null,
  updated_at timestamptz not null
);

Deployment table:

create table deployment_topology (
  id uuid primary key,
  deployment_code text not null unique,
  deployment_type text not null,
  environment text not null,
  cloud_provider text,
  region text,
  cluster_id text,
  database_cluster_id text,
  message_broker_cluster_id text,
  search_cluster_id text,
  status text not null,
  created_at timestamptz not null,
  updated_at timestamptz not null
);

Tenant config:

create table tenant_configuration (
  id uuid primary key,
  tenant_id uuid not null references tenant(id),
  config_key text not null,
  config_value text,
  value_type text,
  effective_from timestamptz not null,
  effective_to timestamptz,
  source text,
  created_at timestamptz not null,
  unique (tenant_id, config_key, effective_from)
);

Useful indexes:

create index idx_tenant_status_region
on tenant (status, region_code);

create index idx_tenant_config_current
on tenant_configuration (tenant_id, config_key)
where effective_to is null;

create index idx_deployment_env_region
on deployment_topology (environment, region, status);

25. Java/JAX-RS Backend Implications

Tenant context should be resolved at request boundary.

Sources:

  • authenticated token claim,
  • hostname/subdomain,
  • path/header,
  • API client registration,
  • internal service context,
  • message/event metadata.

Request handling:

TenantResolver
  -> validates tenant status
  -> attaches TenantContext
  -> all repositories/services require tenant context

Avoid optional tenant filters.

Repository methods should require tenant_id for tenant-owned data:

Quote findById(TenantId tenantId, QuoteId quoteId);

Do not expose findById(quoteId) if shared tenant DB.


26. API Impact

API should define tenant scoping.

Options:

GET /quotes/{id}
X-Tenant-Id: tenant-id

or tenant resolved by auth/subdomain.

For public APIs, do not let clients arbitrarily pass tenant ID unless authorized.

Error cases:

  • tenant not found,
  • tenant suspended,
  • tenant mismatch with token,
  • tenant not configured,
  • feature disabled for tenant,
  • wrong environment.

Use stable error codes.


27. Security and Privacy

Tenant isolation controls:

  • tenant-aware auth claims,
  • tenant-aware row filtering,
  • tenant-aware cache keys,
  • tenant-aware events,
  • tenant-aware search filters,
  • tenant-aware exports,
  • tenant-aware admin support access,
  • audit cross-tenant access,
  • tenant-specific encryption keys if required,
  • tenant-specific retention policy if required.

Support/admin cross-tenant access must be controlled and audited.


28. Data Quality Checks

Examples:

-- Tenant-owned rows missing tenant_id
-- Conceptual; run per table where applicable.
select id
from quote
where tenant_id is null;

-- Active tenant without deployment
select id, tenant_code
from tenant
where status = 'ACTIVE'
  and deployment_id is null;

-- Current config duplicate
select tenant_id, config_key, count(*)
from tenant_configuration
where effective_to is null
group by tenant_id, config_key
having count(*) > 1;

More advanced checks:

  • cross-tenant reference,
  • event tenant mismatch,
  • cache/search tenant leakage,
  • tenant suspended but jobs still running,
  • data residency mismatch.

29. Failure Modes

Failure modeSymptomLikely causePrevention
Cross-tenant data leakCustomer sees other customerMissing tenant filterTenant context required everywhere
Cache tenant leakWrong pricing/status shownCache key lacks tenantTenant-aware cache key
Search leakSearch returns other tenant docsMissing tenant filter/index isolationTenant-filtered search
Wrong event processedConsumer updates wrong tenantEvent lacks tenant/environmentTenant-aware event envelope
Data residency breachData stored in wrong regionDeployment topology not modelledResidency metadata/validation
Background job overreachBatch updates all tenantsNo tenant scopeTenant-aware job model
Tenant config driftBehavior inconsistentConfig not versioned/auditedEffective-dated config
On-prem upgrade failsMigration assumes SaaSDeployment differences hiddenDeployment model
Tenant decommission incompleteData remains in cache/searchDerived copy registry missingDecommission workflow
Reporting mixes tenantsKPI leak/wrong aggregateDataset lacks tenant scopeTenant-aware analytics

30. PR Review Checklist

When reviewing tenant/deployment changes, ask:

  • Is this data tenant-owned?
  • Is tenant_id required and indexed?
  • Are unique constraints tenant-scoped?
  • Are APIs resolving tenant securely?
  • Are cache keys tenant-aware?
  • Are events tenant/environment-aware?
  • Are search/read models tenant-filtered?
  • Are background jobs scoped by tenant?
  • Does data residency apply?
  • Does deployment topology affect integration endpoint?
  • Is tenant config versioned/effective-dated?
  • Does this support SaaS, dedicated, on-prem, or hybrid?
  • Does purge/decommission cover derived stores?
  • Is cross-tenant admin access audited?

31. Internal Verification Checklist

Verify these in the internal CSG/team context:

  • Whether product is single-tenant, multi-tenant, dedicated, on-prem, or hybrid.
  • Actual meaning of tenant vs customer/account.
  • Whether tenant_id exists on operational tables.
  • Whether tenant isolation is DB-per-tenant, schema-per-tenant, or row-level.
  • Tenant-aware cache/search/event conventions.
  • Tenant-aware unique constraint strategy.
  • Tenant provisioning/decommissioning process.
  • Data residency requirements by customer/region.
  • On-prem deployment differences.
  • Tenant-specific feature flags/config.
  • Support/admin cross-tenant access process.
  • Incidents involving cross-tenant leak, tenant config drift, wrong environment, or tenant migration issues.

32. Summary

Multi-tenancy is a data modelling boundary.

A strong model must define:

  • tenant,
  • customer/account distinction,
  • deployment topology,
  • environment,
  • region/data residency,
  • tenant-scoped IDs,
  • tenant-aware indexes,
  • tenant-aware events,
  • tenant-aware cache/search/read models,
  • tenant configuration,
  • feature flags,
  • provisioning,
  • migration,
  • decommissioning,
  • background job scope,
  • support/admin access audit.

The key principle:

If tenant boundary is not explicit in your data model and every derived copy, it will eventually be violated by a query, cache, event, search index, batch job, export, or support tool.

Lesson Recap

You just completed lesson 61 in deepen practice. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.