Skip to main content
emnode
Cost

Right-size Azure Cosmos DB throughput with autoscale

One capability across every Cosmos DB database and container: stop paying for a fixed ceiling of request units around the clock when the workload only needs them at peak, by letting autoscale scale the RU/s down when traffic falls.

14 min·10 sections·AZURE

Last reviewed

Right-sizing Cosmos DB throughput: the basics

What does an over-provisioned Cosmos DB database actually look like?

Azure Cosmos DB bills provisioned throughput in request units per second, RU/s, and on the standard manual model you pay for the ceiling you set every hour of every day, whether or not the workload uses it. A container provisioned at a flat 10,000 RU/s costs the same at 3am with no traffic as it does at the midday peak. Most workloads are not flat: they have a busy window and a long quiet tail, so a fixed manual ceiling means paying peak rates for off-peak hours.

Autoscale changes the billing shape. You set a maximum, Tmax, and Cosmos DB scales the actual throughput T between ten per cent and one hundred per cent of that maximum based on real consumption, so 0.1 times Tmax is the floor and Tmax is the ceiling. You are billed each hour for the highest throughput the system scaled to during that hour, not for the ceiling. When the workload is idle overnight, the database drifts down toward its floor and the bill follows it down, instead of sitting pinned at the manual ceiling.

Most over-provisioning is inertia, not intent. A container sized for a launch-day peak that never got revisited, a database left at the default ceiling a quickstart created, a manual setting that made sense for last year's traffic and was never tuned down. Azure Advisor watches the gap: its cost recommendation 'Enable autoscale on your Azure Cosmos DB database or container' compares the manual RU/s you provisioned against what autoscale would have scaled to over the past seven days, and surfaces the accounts where the bill is paying for a ceiling the workload rarely reaches.

In this lesson you will learn how Azure Cosmos DB charges for provisioned throughput, why a manual RU/s ceiling overpays for variable workloads, and how to use the Azure Advisor autoscale recommendation to find and right-size the databases and containers where the bill is paying for a ceiling the workload rarely reaches. You will see how to read the seven-day savings estimate, when autoscale wins against the documented break-even, and how to make the change safely in the CLI and in Bicep.

Fun fact

The ceiling you pay for at 3am

On manual provisioned throughput, a Cosmos DB container set to 10,000 RU/s costs exactly the same in the dead of night with zero traffic as it does at the busiest minute of the day. The meter does not care that the workload is asleep. Autoscale was built for precisely this shape of bill: it scales the throughput down to as low as ten per cent of your maximum when demand falls and bills you per hour for the highest point it actually reached, so the quiet hours finally cost less than the busy ones. The catch is the 1.5x per-unit rate, which is why autoscale saves money only when the workload spends enough of its time scaled down, below roughly two-thirds average utilisation.

Finding over-provisioned throughput across a subscription

Priya is the platform lead at a SaaS company whose Cosmos DB spend has crept up quarter on quarter. Azure Advisor's cost tab shows several 'Enable autoscale on your Azure Cosmos DB database or container' recommendations, each with a seven-day savings estimate, spread across containers that were provisioned manually during the early build-out and never revisited.

Rather than flip everything to autoscale on instinct, Priya starts by reading what each container is actually provisioned at and how it is configured, so the genuinely variable workloads can be separated from the steady high-utilisation ones before anything changes.

Start by reading the current throughput settings on a container Advisor flagged. The offer details show whether it is manual or already autoscale, and at what level.

$ az cosmosdb sql container throughput show --account-name cosmosprod --database-name app --name orders --resource-group rg-data --query "resource.{manual:throughput, autoscaleMax:autoscaleSettings.maxThroughput}" -o table
Manual AutoscaleMax
-------- --------------
10000
# Manual 10000 RU/s, billed flat 24/7. Advisor's 7-day estimate says autoscale saves here.

A container sitting on a flat manual ceiling with an empty autoscale field, flagged by Advisor, is a candidate for the change. Confirm the workload is variable before migrating.

How Azure Advisor decides a database should move to autoscaledeep dive

The recommendation 'Enable autoscale on your Azure Cosmos DB database or container' is driven by your real consumption. Azure Advisor looks at the past seven days of usage on a manually provisioned database or container, and for each hour it compares the manual RU/s you paid for against the throughput autoscale would have scaled to that hour. It sums the difference across the window into an estimated saving, so the figure on the recommendation is grounded in how the workload actually behaved, not a generic model.

The billing mechanics underneath are what make the saving possible. On manual provisioning you pay for the ceiling every hour. On autoscale, Cosmos DB scales the instantaneous throughput T within the band 0.1 times Tmax to Tmax, and you are billed for the highest T the system reached in each hour. A workload that idles down to its floor overnight is billed near the floor for those hours. The reason this is not free money is the rate: autoscale is priced at 1.5 times the manual rate per RU/s, so the break-even sits where average utilisation is about 66.7 per cent of the ceiling. Below that, the hours spent scaled down more than pay for the premium; above it, a steady workload is cheaper on manual.

There is one case where the trade-off disappears. For an account configured with multi-region writes and more than one region, Microsoft documents that the per-RU rate is the same for manual and autoscale, so autoscale carries no premium and is the recommended default regardless of utilisation. Knowing which regime a flagged account is in tells you whether the 66.7 per cent test even applies.

What is the impact of leaving throughput over-provisioned?

The direct impact is recurring overspend. A manual ceiling sized for the peak is paid in full for every off-peak hour, so a workload with a pronounced daily or weekly cycle leaks money continuously on the hours it sits idle. Multiply that across several containers that were provisioned during a build-out and never tuned, and the Cosmos DB line carries a standing cost that buys no extra capability, just unused headroom billed around the clock.

The second-order impact is drift that nobody is watching. Manual throughput is a number someone set once; without a review loop, it stays at last year's peak even as traffic patterns change. Azure Advisor's autoscale recommendation is the watching for you, but only if someone acts on it. Left alone, the gap between provisioned and used widens quietly and the overspend compounds month after month.

The trade-off to respect is throttling. Throughput exists to serve the workload, so the saving must never come at the cost of capacity. If Tmax is set below the real peak, requests hit rate limits, so the right move is to set the autoscale maximum at or above the workload's true peak and let it scale down from there. Done correctly, autoscale removes the overspend without touching performance, because the ceiling is preserved and only the off-peak hours get cheaper.

How do you right-size throughput safely?

Work the recommendation as one loop rather than flipping switches at random. The order matters: confirm the workload is genuinely variable and set the peak ceiling correctly before you migrate, so the saving never costs you performance.

1. Read Advisor and the real utilisation

Start from the 'Enable autoscale on your Azure Cosmos DB database or container' recommendations and their seven-day savings estimates. For each flagged container or database, check the average RU/s utilisation against the manual ceiling. The 66.7 per cent break-even is the test: below it, autoscale saves; above it, manual is cheaper.

2. Separate variable workloads from steady ones

Autoscale wins on spiky or cyclical workloads that spend real time scaled down. A container that runs hot near its ceiling most of the day should stay on manual, because the 1.5x rate would raise its bill. Treat multi-region-write accounts as a special case: there autoscale carries no premium, so it is the default.

3. Set Tmax at or above the true peak

The autoscale maximum must cover the workload's real peak so requests are never throttled. Autoscale scales between ten per cent and one hundred per cent of Tmax, so the off-peak hours get cheaper while the ceiling is preserved. Migrate, then set the maximum to a value that comfortably covers peak demand.

4. Verify the saving and keep the loop running

After migrating, confirm the new bill tracks usage and that no throttling appeared, then revisit periodically. Traffic patterns change, so a workload that was steady can become variable and vice versa. The change reverses in one command, so a wrong call is cheap to undo and the review is worth repeating each quarter.

# Migrate a manually provisioned container to autoscale (reversible: pass 'manual' to switch back).
az cosmosdb sql container throughput migrate \
  --account-name cosmosprod \
  --database-name app \
  --name orders \
  --resource-group rg-data \
  --throughput-type autoscale

# Set the autoscale maximum (Tmax) at or above the workload's true peak so it never throttles.
# Autoscale scales between 10% and 100% of this value and bills per hour for the highest point reached.
az cosmosdb sql container throughput update \
  --account-name cosmosprod \
  --database-name app \
  --name orders \
  --resource-group rg-data \
  --max-throughput 10000

# In Bicep, provision autoscale on the container with autoscaleSettings.maxThroughput.
# Note: set EITHER autoscaleSettings OR throughput on options, never both, or the deploy fails.
#
# resource container 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2024-11-15' = {
#   name: '${account.name}/${database.name}/orders'
#   properties: {
#     resource: {
#       id: 'orders'
#       partitionKey: { paths: ['/customerId'], kind: 'Hash' }
#     }
#     options: {
#       autoscaleSettings: {
#         maxThroughput: 10000
#       }
#     }
#   }
# }

Quick quiz

Question 1 of 5

Azure Advisor recommends 'Enable autoscale on your Azure Cosmos DB database or container'. How does it produce the savings estimate attached to it?

You can now treat Cosmos DB throughput as a managed cost rather than a number set once and forgotten: read Azure Advisor's seven-day savings estimate, confirm the workload is genuinely variable, move the below-break-even ones to autoscale with a peak ceiling that protects performance, keep the steady high-utilisation ones on manual on purpose, and revisit the loop as traffic changes. The saving is paying for use instead of a permanent peak, and it reverses in one command if a workload's shape ever changes.

Back to the library