You can implement multi-tenancy with MongoDB Search so that a single instance of an application serves multiple tenants. This page describes design recommendations that apply specifically to MongoDB Search for structuring data and MongoDB Search indexes to scale safely while maintaining tenant isolation.
Importante
Esta orientación supone que se pueden ubicar los inquilinos en una sola VPC. If strict network isolation is required, you must maintain separate projects for each tenant.
Choosing a Strategy
Select a strategy based on your isolation needs, scaling goals, and write-load requirements. The most common strategies are:
A single collection for all tenants - This strategy is recommended for most workloads.
One Database per tenant - This strategy offers high isolation but increases index count.
One Collection per tenant - This strategy is not recommended for MongoDB Search workloads.
A Single Collection for All Tenants (Recommended)
We recommend applying the one collection for all tenants strategy. In this architecture, you store all tenant data in a single collection within a single database. You can distinguish between tenants by including a tenant_id field within each document. This field can be any unique identifier for the tenant, such as a UUID or a tenant name.
Este enfoque centralizado ofrece los siguientes beneficios:
Reduces the number of indexes
Since all tenant data is stored in one collection, you need only a single index that serves documents for all tenants. You avoid hitting the cluster resource limits. For example, you can include the
tenant_idand other shared or tenant-specific fields in a single index.Simplifies maintenance operations
With only a single collection storing all data, you don't have to maintain multiple collections or scale resources across multiple databases. You also simplify backup, sharding, and replication operations as you need to target only a single collection in a single database.
Processes query efficiently
You provide the
tenant_idfield in your queries as a filter using the equals operator within the$search.compound.filterclause.Nota
Your query results will only include documents from the matching tenant, preventing data from leaking across tenants.
If the tenants you colocate share similar access patterns and resource sizes, this strategy also keeps the Lucene index field count low.
Importante
When every tenant has a high write load, colocating all tenants into a single collection might create write contention. In that scenario, consider splitting tenants with the most writes into separate collections so that you can distribute the write load across more underlying resources.
If you have large tenants with unique resourcing or indexing requirements, use a View:
Isolate a tenant. Create a View using a
$matchwith a$exproperation to filter only the tenant's documents.Index separately. Create a MongoDB Search index on the View.
This allows you to customize the index definition for the large tenant without impacting the shared index used by others. All other tenants can use a single index.
We don't recommend exceeding 2500 indexes per cluster because this will generate a high load on the base cluster and risks disrupting your database workload.
If you currently apply the one collection per tenant strategy, we recommend scaling up the base tier to prevent increased replication lagor OOM errors due to resource contention from ahigh number of indexes. We also recommend migrating to the one collection for all tenants strategy.
Handling High-Write Tenants
If specific tenants have massive write loads, they might cause contention in a shared collection. We recommend that you move only the highest-volume tenants to separate collections to distribute the I/O load.
Handling Unique Requirements (Views)
If a tenant requires unique indexing or is significantly larger than others, use a MongoDB View:
One Database Per Tenant
In a database-per-tenant setup, each tenant contains its own database. This setup isolates tenant data, but it also multiplies the number of indexes in the cluster. When each tenant has many indexed fields, the cluster might reach the 2500-index ceiling.
Advertencia
A high index count generates significant load on the base cluster and might disrupt your workload. To keep the cluster stable, carefully monitor the number of indexes and avoid exceeding 2500 indexes in total.
One Collection Per Tenant (Not Recommended)
The collection-per-tenant strategy maps each tenant to its own collection within a shared database. The overhead of maintaining an index per collection might cause:
Increased replication lag
OOM errors due to resource contention
Instability in the base tier
We do not recommend this strategy for MongoDB Search unless tenants have very predictable, lightweight workloads. If you currently use this strategy, migrate toward the one collection for all tenants strategy.
Managing Indexed Fields
Consider the following recommendations to manage indexed fields:
Multi-tenant applications often require custom per-tenant fields that can be searched, sorted, faceted, and filtered. Use a typeSet to dynamically index sub-fields of a path so that MongoDB Search picks up new fields automatically without a full index rebuild. Avoid statically indexing these fields, as doing so triggers a rebuild that adds CPU pressure and consumes up to 2x the index's disk space.
Nota
Risk Too Many Fields
Lucene index performance can degrade if there are more than 1000 distinct fields. You can monitor the number of unique fields in the MongoDB Search index in the MongoDB Search metrics. If you need to support one thousand or more fields, we recommend the following:
Separating a subset of tenants into a separate index using a View, so that the distinct number of fields existing in a single Lucene index remains less than one thousand.
Limiting the number of fields that a single tenant can add.
If you use the attribute pattern to store different keys per tenant, we recommend that you do the following:
Flatten the embedded array of documents using a View.
Create a MongoDB Search index on the View, which is stored on disk.
If you don't flatten the array of documents, you will need to use embeddedDocuments operator queries (similar to $elemMatch) to query the attributes, which is less performant than querying a flattened structure.