Products that support multi-tenancy
The same JWT-based tenant model applies across the platform. Currently supported:| Product | Multi-tenant support | Notes |
|---|---|---|
| Midaz (Ledger + CRM) | ✅ Yes | Organizations, ledgers, accounts, transactions, and balances are scoped to the tenant. |
| Tracer | ✅ Yes | Rules, limits, validations, and audit events are scoped to the tenant. Each tenant has its own rule and limit catalog. |
| Reporter | ✅ Yes | Reports run only over the calling tenant’s data. |
tenantId claim and the service resolves the tenant automatically.
How it works
Tenant isolation is enforced at the application layer through your authentication token.
- You authenticate via Access Manager and receive a JWT.
- That token includes a
tenantIdclaim that identifies your tenant. - On every API request, the platform resolves your tenant from the token automatically.
- All operations — creating organizations, querying ledgers, posting transactions — are scoped to your tenant.
Multi-tenancy is transparent at the API level. Your integration code is the same whether you’re running single-tenant or multi-tenant — the only difference is that multi-tenant deployments require authentication on every request.
How tenant scoping looks in each product
The
tenantId from the JWT scopes every resource the calling user can see or create. The resource model differs per product:
Midaz
A tenant is not the same as an organization. A single tenant can create and manage multiple organizations — for example, to represent subsidiaries, regional branches, or different business units.Tracer
Tracer scopes its catalog directly under the tenant — there is no organization layer.Other products
Reporter and the rest of the platform follow the same pattern: the tenant is the outermost scope, and the JWT is the only source of truth for which tenant the caller belongs to.Data isolation
Tenant data is isolated at the database level. Each tenant operates on a separate database, meaning:
- Data from different tenants is never stored together.
- Queries from one tenant cannot reach another tenant’s data.
- Even if two tenants create identical organization structures, their data remains completely separate.
tenantId claim in your JWT. Depending on the configured isolation mode, tenant data lives in a dedicated database (DATABASE mode) or a dedicated schema within a shared database (SCHEMA mode). There is no way to bypass this through the API.
BYOC operators can choose between database-level or schema-level isolation depending on their infrastructure requirements. See Isolation modes below.
Isolation modes
BYOC operators choose how strongly tenants are isolated at the storage layer. The choice is made per service, so different products — or even different tenants on the same product — can use different modes.
DATABASE— each tenant gets a dedicated database. Maximum isolation, higher cost.SCHEMA— each tenant gets a dedicated schema inside a shared database. Efficient density, lower cost.
DATABASE vs. SCHEMA
| Dimension | DATABASE | SCHEMA |
|---|---|---|
| Physical isolation | Complete — separate database per tenant. | Logical — separate schema inside a shared database. |
| Blast radius | Confined to a single tenant’s database. | Wider — a database-level incident can affect every tenant on that instance. |
| Selective restore | Restore one tenant independently, including point-in-time recovery. | Harder — restores operate on the shared database; per-tenant restore requires extracting a single schema. |
| Cost | Higher — infrastructure scales per tenant. | Lower — tenants share a database instance. |
| Performance isolation | Strong — tenants do not contend within the same database. | Weaker — tenants share instance resources and can contend. |
| Best for | Large, regulated, high-volume, or noisy-neighbor-sensitive tenants. | Many smaller tenants where density and cost efficiency matter. |
Blast radius
Blast radius is the scope of tenants affected when something goes wrong — a failed migration, a corrupt index, a runaway query, or a restore. InDATABASE mode the blast radius is a single tenant, because each tenant is physically separate. In SCHEMA mode the blast radius is wider, because tenants share a database instance and therefore share its failure and maintenance surface. Minimizing blast radius is the main reason regulated or high-value tenants are placed in DATABASE mode.
Other datastores
TheDATABASE vs. SCHEMA distinction above applies to PostgreSQL. Other datastores enforce tenant isolation differently:
- MongoDB uses a separate database per tenant (one database per
tenantId). This applies in bothDATABASEandSCHEMAmodes — MongoDB does not use schemas, so the isolation unit is always a dedicated database named after thetenantId. - RabbitMQ uses a separate virtual host (vhost) per tenant. The vhost is provisioned automatically during the tenant onboarding flow and is named after the
tenantId. Credentials are scoped to the vhost, so a misconfigured consumer cannot reach another tenant’s queues.
Selective restore: per-tenant restore is supported for PostgreSQL and MongoDB — both are tenant-scoped. RabbitMQ state is ephemeral by nature, so “restore” means reprovisioning the vhost and re-delivering any unacked messages from persistent storage where applicable.
Migrating from SCHEMA to DATABASE
A tenant can be promoted fromSCHEMA to DATABASE mode as it grows, without re-issuing tokens or changing the tenant’s identity — isolation is a property of the service, not the tenant.
Provision a dedicated database
The platform provisions a new isolated database for the tenant and runs migrations, as described in automatic provisioning.
Migrate the tenant's data
The tenant’s data is moved from its shared-database schema into the new dedicated database.
What this means for you
If you are a SaaS customer
Nothing changes in how you use the API. Authenticate, get your token, and make requests. The platform handles isolation transparently. You don’t need to manage tenant identifiers or worry about data leaking between customers.If you are a BYOC operator running multi-tenant
You configure which tenants exist and how their databases are provisioned. Your clients authenticate through Access Manager and receive scoped tokens. The platform routes each request to the correct tenant database automatically.If you are running single-tenant (BYOC or local development)
Multi-tenancy is disabled by default. Your existing setup continues to work without changes. No JWT tenant claim is required, and authentication can be optional depending on your configuration.Configuration (BYOC operators)
Multi-tenancy is disabled by default in every product. To enable it, set
MULTI_TENANT_ENABLED=true in the environment of each product you want to run multi-tenant (Midaz, Tracer, Reporter). Once enabled, the product requires authentication on every request and a reachable multi-tenancy service endpoint.
Core settings
These variables apply to every multi-tenant-capable product (Midaz Ledger, Midaz CRM, Tracer, Reporter):| Variable | Description | Default |
|---|---|---|
MULTI_TENANT_ENABLED | Enable multi-tenant mode. When false, the platform runs in single-tenant mode. | false |
MULTI_TENANT_URL | URL of the multi-tenancy service endpoint. Required when multi-tenant is enabled. | — |
MULTI_TENANT_SERVICE_API_KEY | API key for authenticating with the multi-tenancy service. Required when multi-tenant is enabled. | — |
MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC | How often (seconds) the platform revalidates tenant configurations from the service. | — |
MULTI_TENANT_CACHE_TTL_SEC | How long (seconds) tenant configuration is cached locally before re-fetching. Set to 0 to disable caching. | 120 |
Circuit breaker
Protects against multi-tenancy service outages by failing fast when the service is unavailable:| Variable | Description | Default |
|---|---|---|
MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD | Consecutive failures before the circuit opens. | 5 |
MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC | How long (seconds) the circuit stays open before retrying. | 30 |
Redis cache
Multi-tenant mode uses Redis to cache tenant configurations across instances:| Variable | Description | Default |
|---|---|---|
MULTI_TENANT_REDIS_HOST | Redis server hostname. | — |
MULTI_TENANT_REDIS_PORT | Redis server port. | 6379 |
MULTI_TENANT_REDIS_PASSWORD | Redis authentication password. | — |
MULTI_TENANT_REDIS_TLS | Enable TLS for the Redis connection. | false |
CRM-specific settings
These variables are only available in the CRM component and control connection pool behavior for multi-tenant database connections:| Variable | Description | Default |
|---|---|---|
MULTI_TENANT_TIMEOUT | HTTP client timeout (seconds) for requests to the multi-tenancy service. | 30 |
MULTI_TENANT_MAX_TENANT_POOLS | Maximum number of concurrent database connection pools (one per active tenant). | 100 |
MULTI_TENANT_IDLE_TIMEOUT_SEC | How long (seconds) before an idle tenant connection pool is evicted. | 300 |
MULTI_TENANT_ENABLED=true requires PLUGIN_AUTH_ENABLED=true. Authentication must be active for tenant isolation to work — the platform resolves tenants from the JWT claim.Related pages
Automatic provisioning
How a tenant’s databases, broker, and credentials are provisioned.
Use cases
When to choose DATABASE vs. SCHEMA isolation, with a migration path.
Deployment models
Understand the differences between SaaS, BYOC Single-Tenant, and BYOC Multi-Tenant.
Security
Learn about tenant isolation guarantees and the shared responsibility model.
Access Manager
Understand how authentication and JWT-based tenant resolution work.
Organizations
Learn how organizations are structured within a tenant.

