Skip to content

Commit 4cd1357

Browse files
Merge pull request #244740 from ealsur/users/ealsur/multitenant
Cosmos DB: SDK - Adding multitenant recommendations
2 parents 388861d + 4f5a959 commit 4cd1357

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

articles/cosmos-db/nosql/best-practice-dotnet.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ author: StefArroyo
55
ms.service: cosmos-db
66
ms.subservice: nosql
77
ms.topic: how-to
8-
ms.date: 03/14/2023
8+
ms.date: 07/12/2023
99
ms.author: esarroyo
1010
ms.reviewer: mjbrown
1111
ms.custom: cosmos-db-video, devx-track-dotnet
@@ -98,7 +98,7 @@ services.AddSingleton<CosmosClient>(serviceProvider =>
9898

9999
## Best practices when using Gateway mode
100100

101-
Increase `System.Net MaxConnections` per host when you use Gateway mode. Azure Cosmos DB requests are made over HTTPS/REST when you use Gateway mode. They're subject to the default connection limit per hostname or IP address. You might need to set `MaxConnections` to a higher value (from 100 through 1,000) so that the client library can use multiple simultaneous connections to Azure Cosmos DB. In .NET SDK 1.8.0 and later, the default value for `ServicePointManager.DefaultConnectionLimit` is 50. To change the value, you can set `Documents.Client.ConnectionPolicy.MaxConnectionLimit` to a higher value.
101+
Increase `System.Net MaxConnections` per host when you use Gateway mode. Azure Cosmos DB requests are made over HTTPS/REST when you use Gateway mode. They're subject to the default connection limit per hostname or IP address. You might need to set `MaxConnections` to a higher value (from 100 through 1,000) so that the client library can use multiple simultaneous connections to Azure Cosmos DB. In .NET SDK 1.8.0 and later, the default value for `ServicePointManager.DefaultConnectionLimit` is 50. To change the value, you can set `CosmosClientOptions.GatewayModeMaxConnectionLimit` to a higher value.
102102

103103
## Best practices for write-heavy workloads
104104

@@ -107,12 +107,26 @@ For workloads that have heavy create payloads, set the `EnableContentResponseOnW
107107
> [!IMPORTANT]
108108
> Setting `EnableContentResponseOnWrite` to `false` will also disable the response from a trigger operation.
109109
110+
## Best practices for multi-tenant applications
111+
112+
Applications that distribute usage across multiple tenants where each tenant is represented by a different database, container, or partition key **within the same Azure Cosmos DB account** should use a single client instance. A single client instance can interact with all the databases, containers, and partition keys within an account, and it's best practice to use the [singleton pattern](performance-tips-dotnet-sdk-v3.md#sdk-usage).
113+
114+
However, when each tenant is represented by a **different Azure Cosmos DB account**, it's required to create a separate client instance per account. The singleton pattern still applies for each client (one client for each account for the lifetime of the application), but if the volume of tenants is high, the number of clients can be difficult to manage. [Connections](sdk-connection-modes.md#direct-mode) can increase beyond the limits of the compute environment and cause [connectivity issues](conceptual-resilient-sdk-applications.md#client-instances-and-connections).
115+
116+
It's recommended in these cases to:
117+
118+
* Understand the limitations of the compute environment (CPU and connection resources). We recommend using VMs with at least 4-cores and 8-GB memory whenever possible.
119+
* Based on the limitations of the compute environment, determine the number of client instances (and therefore number of tenants) a single compute instance can handle. You can [estimate the number of connections](sdk-connection-modes.md#volume-of-connections) that will be opened per client depending on the connection mode chosen.
120+
* Evaluate tenant distribution across instances. If each compute instance can successfully handle a certain limited amount of tenants, load balancing and routing of tenants to different compute instances would allow for scaling as the number of tenants grow.
121+
* For sparse workloads, consider using a Least Frequently Used cache as the structure to hold the client instances and dispose clients for tenants that haven't been accessed within a time window. One option in .NET is [MemoryCacheEntryOptions](/dotnet/api/microsoft.extensions.caching.memory.memorycacheentryoptions), where [RegisterPostEvictionCallback](/dotnet/api/microsoft.extensions.caching.memory.memorycacheentryextensions.registerpostevictioncallback) can be used to **dispose inactive clients** and [SetSlidingExpiration](/dotnet/api/microsoft.extensions.caching.memory.memorycacheentryextensions.setslidingexpiration) can be used to define the maximum time to hold inactive connections.
122+
* Evaluate using [Gateway mode](sdk-connection-modes.md#available-connectivity-modes) to reduce the number of network connections.
123+
* When using [Direct mode](sdk-connection-modes.md#direct-mode) consider adjusting [CosmosClientOptions.IdleTcpConnectionTimeout](/dotnet/api/microsoft.azure.cosmos.cosmosclientoptions.idletcpconnectiontimeout) and [CosmosClientOptions.PortReuseMode](/dotnet/api/microsoft.azure.cosmos.cosmosclientoptions.portreusemode) on the [direct mode configuration](tune-connection-configurations-net-sdk-v3.md) to close unused connections and keep the [volume of connections](sdk-connection-modes.md#volume-of-connections) under control.
124+
110125
## Next steps
111126

112127
For a sample application that's used to evaluate Azure Cosmos DB for high-performance scenarios on a few client machines, see [Performance and scale testing with Azure Cosmos DB](performance-testing.md).
113128

114129
To learn more about designing your application for scale and high performance, see [Partitioning and scaling in Azure Cosmos DB](../partitioning-overview.md).
115130

116131
Trying to do capacity planning for a migration to Azure Cosmos DB? You can use information about your existing database cluster for capacity planning.
117-
* If all you know is the number of vCores and servers in your existing database cluster, read about [estimating request units using vCores or vCPUs](../convert-vcore-to-request-unit.md)
118132
* If you know typical request rates for your current database workload, read about [estimating request units using Azure Cosmos DB capacity planner](estimate-ru-with-capacity-planner.md)

articles/cosmos-db/nosql/performance-tips-dotnet-sdk-v3.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ author: seesharprun
55
ms.service: cosmos-db
66
ms.subservice: nosql
77
ms.topic: how-to
8-
ms.date: 03/31/2022
8+
ms.date: 07/12/2023
99
ms.author: sidandrews
1010
ms.devlang: csharp
1111
ms.custom: devx-track-dotnet, contperf-fy21q2, ignite-2022
@@ -109,7 +109,7 @@ When it's running on the TCP protocol, the client optimizes for latency by using
109109
In scenarios where you have sparse access, and if you notice a higher connection count when compared to Gateway mode access, you can:
110110

111111
* Configure the [CosmosClientOptions.PortReuseMode](/dotnet/api/microsoft.azure.cosmos.cosmosclientoptions.portreusemode) property to `PrivatePortPool` (effective with framework versions 4.6.1 and later and .NET Core versions 2.0 and later). This property allows the SDK to use a small pool of ephemeral ports for various Azure Cosmos DB destination endpoints.
112-
* Configure the [CosmosClientOptions.IdleConnectionTimeout](/dotnet/api/microsoft.azure.cosmos.cosmosclientoptions.idletcpconnectiontimeout) property as greater than or equal to 10 minutes. The recommended values are from 20 minutes to 24 hours.
112+
* Configure the [CosmosClientOptions.IdleTcpConnectionTimeout](/dotnet/api/microsoft.azure.cosmos.cosmosclientoptions.idletcpconnectiontimeout) property as greater than or equal to 10 minutes. The recommended values are from 20 minutes to 24 hours.
113113

114114
<a id="same-region"></a>
115115

@@ -145,7 +145,9 @@ Middle-tier applications that don't consume responses directly from the SDK but
145145

146146
**Use a singleton Azure Cosmos DB client for the lifetime of your application**
147147

148-
Each `CosmosClient` instance is thread-safe and performs efficient connection management and address caching when it operates in Direct mode. To allow efficient connection management and better SDK client performance, we recommend that you use a single instance per `AppDomain` for the lifetime of the application.
148+
Each `CosmosClient` instance is thread-safe and performs efficient connection management and address caching when it operates in Direct mode. To allow efficient connection management and better SDK client performance, we recommend that you use a single instance per `AppDomain` for the lifetime of the application for each account your application interacts with.
149+
150+
For multi-tenant applications handling multiple accounts, see the [related best practices](best-practice-dotnet.md#best-practices-for-multi-tenant-applications).
149151

150152
When you're working on Azure Functions, instances should also follow the existing [guidelines](../../azure-functions/manage-connections.md#static-clients) and maintain a single instance.
151153

0 commit comments

Comments
 (0)