Keeping your Costs Low in Cosmos DB

Craig O Connor
Version 1
Published in
6 min readJun 21, 2021

When I have discussions with peers and colleagues at Version 1 and mention I’m working on a project using Cosmos DB (by Microsoft Azure), usually the first question I get asked is about the cost, so I thought it might be useful to write a short blog explaining how pricing works for Cosmos DB.

Cosmos DB provides a lot of tools to let you control and limit the costs to the point that it can be a very cost effective solution, depending on your requirements. Below I will go over the different pricing options and offer some tips on the best options based on my experience. Before we can look at the different options available in Cosmos DB, I’ll briefly explain Request Units (RUs) as the pricing options are all based around RUs.

Request Units (RUs)

“Request unit is a performance currency abstracting the system resources such as CPU, IOPS, and memory that are required to perform the database operations supported by Azure Cosmos DB.”

https://docs.microsoft.com/en-us/azure/cosmos-db/request-units

The cost of every database operation in Cosmos DB is expressed using RUs. This is important to understand, as the pricing model for Cosmos DB is structured around RUs. Cosmos DB requires you to pay for the RUs you use, either by provisioning them up front, or just paying for the RUs you use. If your requests exceed the provisioned RUs you are either going to take a performance hit, or increase your costs.

So if you keep your queries and data small, the number of RUs you use will be lower. You can also manually set up indexes etc. to try and reduce the RUs used in each operation. There is a lot more information on Request Units at the link above, and I will write about tips for keeping your RUs low in the future.

Serverless or Provisioned Throughput?

When you set up a new Cosmos DB database you will have to choose between a Serverless or Provisioned Throughput capacity mode. Choosing the best option for your requirements is key to keeping the costs low when using CosmosDB.

Note: You cannot swap between the Serverless and Provisioned Throughput capacity options once the resource has been created.

Provisioned Throughput

When you choose the provisioned throughput mode, you are deciding what the maximum RU/s you will need and provisioning that up front. You can change the maximum value at any time, and you are billed hourly for the maximum RU provisioned in that hour.

E.g. If you set the max RUs to 10,000 and then down to 5,000 within the same hour, you will be charged 10,000 for the first hour and then continue to be charged for 5,000 RUs every hour after that until you change it again.

Note: You can choose to provision throughput on each individual container, or share the throughput across all containers in your database. The options described below work the same regardless, though your costs will likely be higher if you provision at the container level, but you will have more flexibility in terms of performance.

Once you have created your Provisioned Throughput Cosmos DB resource, there are two options for managing your available RUs — Manual or Autoscale. You can change between these at any time.

  • Manual

So in this example, I’ve set this database to have a throughput of 400 and I’ve gotten an estimated cost for the month. No matter how many requests the database received, that is the cost I will be charged at the end of the month. I can change this as often as I like, and as described above, you are charged for the highest provisioned value used every hour. Any changes made here take effect immediately.

Note: If you start using more RUs than you have available, you will get a 429 error back as your response. Depending on your use case, it might be ok to handle this by just waiting a short while and retrying. As the load on the database reduces, you will eventually get a success response back. You can also manually scale up the throughput to what you need. If your traffic fluctuates significantly throughout the day or week, then the autoscale option is probably more suitable.

  • Autoscale

As you can see above, there is an autoscale option and this allows you to set maximum throughput, and Cosmos DB will automatically scale up and down as needed, but never exceed the maximum value you’ve chosen.The minimum allowed values here at the time of writing is 4000 RU/s. This means it will scale all the way down to 400 RU/s when quiet but scale up to a maximum of 4000RU/s as needed, when the load increased.

Note: The minimum RU/s value starts out as 400 RU/s, but as the amount of data in your database grows the lowest allowable value does start to increase in chunks of 100 RU/s. So if your data grows sufficiently large, your costs may increase as as the lowest value changes from 400RU/s to 500RU/s and so on.

If this is a concern, you may need limit the data you save in Cosmos DB, perhaps deleting or archiving older data that is no longer needed. This applies to both the Manual and Autoscale options.

Autoscale is obviously the more flexible option, but it can also be more expensive than Manual if your required throughput is low.Thankfully you can change between the Autoscale and Manual options at any time, so you can experiment with this to find what is most suitable for your requirements.

Serverless

This is the newest option added to Cosmos DB and this is probably the cheapest option albeit with some limitations.

If you choose the serverless model, you only pay for the RUs you consume. So in the scenario where your traffic is quite light and intermittent, this could work out as significantly cheaper than the provisoned throughput options described above, The other benefit here is that serverless will scale up and down to handle any increased load, so you don’t need to worry about manually configuring the maximum RUs and autoscale settings etc.

There are some limitations to be aware of.

  • The amount you are billed is less predictable, so you need to monitor the usage and possibly set up alerts etc. in Azure Monitor to notify you if the RU consumption ever goes higher than the range you are expecting.
  • Serverless containers have a size limit of 50Gb of data and indexes per container.
  • The maximum RU/s is 5000, so if your usage exceeds that, your performance will take a hit.
  • Can only run in a single region.

Note: Serverless has only been added relatively recently so I wouldn’t be surprised if changes to the above limitations are added in the future.

Summary

As described above, there are 3 main pricing options for Cosmos DB

  • Serverless — For most use cases this is the cheapest option. You only pay for the RUs you use, but pricing can be unpredictable and there are significant limitations on storage space and performance.
  • Standard Provisioned Throughput — You choose a maximum value of available RUs and you are charged hourly for that throughput even if it isn’t used. The billing is predictable, and you can increase or decrease the provisioned RUs at any time.
  • Autoscale Provisioned Throughput — Very similar to the standard Provisioned Throughput option, but this option allows you to set a maximum RU value, and it will automatically scale down to 10% of that maximum when the database is quiet, and scale back up as needed.

Thank you for reading this article.

If you have any feedback or questions, please feel free to add a comment and I’ll get back to you asap.

About the Author

Craig O Connor is currently a Tech/Team Lead at Version 1.

--

--