Concerns on using Azure cosmos db for a multi tenant architecture.

Gebriel Tadesse 0 Reputation points
2024-03-25T06:55:18.5966667+00:00

I am creating a B2B SaaS, which is a multi tenant application. At first I decided to use azure SQL database, however I feel cosmos DB would be a better fit for my needs. The issues I face are mainly on the limitations set for azure cosmos DB resource wise. These limitations make development much more complex, than if I went with SQL database: https://learn.microsoft.com/en-us/azure/azure-sql/database/resource-limits-logical-server?view=azuresql which would allow me 1,250,000 databases per subscription, if i went with a database per tenant approach, using EF core with something like finbuckle package.

For cosmos db, my architecture plans are container per tenant, looking at the limitations: https://learn.microsoft.com/en-us/azure/cosmos-db/concepts-limits I'm allowed 500 containers or databases per account, as well as 50 accounts per subscription. Which would mean about 25,000 containers in a single subscription?

Total count of both with an account. (1 database and 499 containers, 250 databases and 250 containers, etc.)

I'll be using asp.net web api which will be shared across all tenants. As well using the Azure Cosmos DB .NET SDK. I'm guessing this would mean using ARM templates with the azure resource manager SDK, in order to create new databases, accounts and subscriptions with a service principle. As well more complexity is added for the cosmos SDK: https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/best-practice-dotnet#best-practices-for-multi-tenant-applications

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. 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 can increase beyond the limits of the compute environment and cause connectivity issues.

All of this has me wondering, if cosmos DB is the correct choice. If there were no limits on the number of containers in a single database, development wise everything would be very simple. As well sense I'm using .net it makes sense to pick azure for my project. I'm simply wondering what people would suggest I do? Is this limit something that simply can't be raised? Am I forced to deal with the complexity mentioned above if I do go with cosmos DB? Is there anything that exists that would aid my team and I development wise to implement this logic? Are there any code examples which shows how to implement such logic?

Also another thing to note, we are in the processes of creating our MVP. Am I over engineering by implementing such logic now? Should this be something we consider handling latter down the road as we scale? I feel like such logic should be handled now, am I wrong? We expect to have a large number of tenants, so its not a pre set amount like 100 or 1000 and the expected growth is unknown. We want to implement logic when a tenant signs up and pays, that is when they get there container created. All of this would be handled programmatically by the asp.net web api. As well a master database will be used to keep track of tenants, which subscription/account they belong to, which database and connection strings. The reason I am doing container pre tenant is due to Noisy neighbor prevention. I would love some guidance and general thoughts on this.

Azure Cosmos DB
Azure Cosmos DB
An Azure NoSQL database service for app development.
1,439 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Amira Bedhiafi 15,041 Reputation points
    2024-03-25T15:59:15.35+00:00

    I agree with you about your concerns, especially regarding scalability, resource management, and the complexity of handling multiple tenants efficiently.

    For the limitations :

    As you've noted, Cosmos DB has a limitation of 500 containers or databases per account and 50 accounts per subscription, summing up to a theoretical maximum of 25,000 containers for a single subscription. If you are dealing with an SaaS apps with a rapid growth or a marge number of tenants, this won't be the best solution in my opinion.

    Also, Cosmos DB accounts and containers can add complexity, especially when it comes to provisioning and managing resources in a dynamic way.

    With ARM templates and the Azure Cosmos DB .NET SDK to automate these tasks, you can bypass some of the complexity, but it still requires more effort in automation and monitoring infrastructure.

    What do you need to consider for multi-tenant architecture?

    If applications have multiple tenants and if there is only one Azure Cosmos DB account it is recommendable to use a single client instance per each account On the one side, this is a efficient way for scaleable management of multiple accounts but the problem might occur with internet connectivity since the limit of the compute is enforced. The database-per-construction technique (1 per each customer using either a database or a container) provides the highest level of isolation and capacity but at the cost of greater complexity and resource divide. Collaterally, this can be handled through use of a multi-tenant architecture with shared resources, where partitioned data is determined by tenant ID. However, you will require thorough design to overcome noisy neighbors problem and guarantee security and performance isolation.

    And for development ?

    Balancing the need for scalability and flexibility against the risks of overengineering is an MVP's main priority, in particular given its embryonic character. Developing a multi tenant architecture on the first instance may take a long term and cost to development in terms of time and cost. It can be more practical to develop a simple architecture and then strategize for scalability when your user base increases.

    As a starting point it is important to create an application with prospects to easily develop it in the future. This implies making sure that your building can grow by adding more complex multi-tenant solutions, but the existing infrastructure can support the future needs.

    0 comments No comments

  2. GeethaThatipatri-MSFT 27,017 Reputation points Microsoft Employee
    2024-03-28T01:08:57.84+00:00

    @Gebriel Tadesse  Thanks for posting your question in the Microsoft Q&A forum.

    Apologize for the delayed response.

     As Per our resource limits, you may request an increase to 1000 accounts per subscription by creating an Azure Support request, which would mean 499,000 containers per subscription. Would this still pose significant complexity for your MVP?

     Additionally, have you considered designating tenant by partition key? Here are the considerations for this approach: Partitioning and horizontal scaling - Azure Cosmos DB | Microsoft Learn

     As for the question on whether Cosmos DB or SQL DB would be better suited for your needs, could you please elaborate on the use case, expected traffic pattern, etc.?

    Regards

    Geetha