11 Nov 2026
Right-sizing Azure SQL.
Your database is provisioned for a peak that happens twice a year.
Someone picked the tier at launch, the month-end close ran fine, and nobody opened Compute + storage again. Azure SQL gives you three ways to pay for the same database, and each one bills a different shape of load. Which one is cheapest depends on that shape, so read it before you compare prices.
01Read what the database did, not what it was sized for
Two places hold the history, and they answer different questions.
sys.resource_stats,
queried from the logical server's master, keeps about 14 days in
five-minute rows: CPU, data IO and log write, each as a percentage of the
tier's limit. Azure Monitor keeps
platform
metrics for 93 days, though a single chart only shows 30 of them at a time.
Fourteen days gives you the shape of a normal fortnight. Ninety-three is what
catches the month-end and quarter-end peaks the fortnight missed.
-- run in master; one row per database, quietest first
SELECT database_name, sku,
AVG(avg_cpu_percent) AS avg_cpu,
MAX(avg_cpu_percent) AS peak_cpu,
MAX(avg_data_io_percent) AS peak_data_io,
MAX(avg_log_write_percent) AS peak_log_write,
SUM(CASE WHEN avg_cpu_percent > 80 THEN 5 ELSE 0 END) AS minutes_above_80
FROM sys.resource_stats
WHERE start_time > DATEADD(day, -14, GETUTCDATE())
GROUP BY database_name, sku
ORDER BY avg_cpu;
Two things to watch out for. Microsoft notes that idle databases may not have a row for every five-minute window, so the average covers the rows that exist, not 14 days of wall-clock time. And on a DTU database, don't stop at the CPU column. The DTU percentage metric is the highest of CPU, data IO and log IO at each point. A database pinned at 90% DTU can be IO-bound with idle cores, and a bigger CPU won't fix that.
02Three ways to pay for the same database
| DTU | vCore provisioned | vCore serverless | |
|---|---|---|---|
| You pay for | A bundle of CPU, memory and IO, storage included | The vCores you provision, storage apart | The compute you use, between a min and a max |
| Billed | By DTUs allocated | Per hour | Per second, higher unit price |
| When idle | Full price | Full price | Minimum compute, then storage only once paused |
| Discounts | Hybrid Benefit is a vCore feature | Hybrid Benefit, reservations | Neither applies |
| Fits | Steady load, fixed monthly bill | Regular load, high average use | Intermittent load, low average, tolerates a warm-up |
The purchasing models page carries most of this table. The rest comes from the serverless pages. Serverless only exists in the vCore model, on General Purpose and Hyperscale with standard-series hardware, so a DTU database has to change model before it can pause. Microsoft's own split is simple: serverless for intermittent, unpredictable use with a low average, provisioned for regular use with a high one.
03What one quiet day costs on serverless
Serverless bills, each second, the largest of the minimum vCores, the vCores used, and memory divided by 3 GB. Microsoft's worked example is a General Purpose database with 1 to 4 vCores, a six-hour auto-pause delay and two busy hours a day. Here it is next to the same database provisioned at 4 vCores, sized for the peak.
Two lines in that example are easy to skim past. The second busy hour bills 4 vCores even though only 1 is in use, because 12 GB of memory divided by 3 outweighs it. And hours 2 to 8 bill the minimum, because the database is idle but not yet paused. Microsoft prices the day at about $7.31 of compute at an example unit rate. The 6.9× is our arithmetic: 345,600 divided by 50,400.
04Why serverless databases don't pause
Auto-pause needs zero sessions and zero user CPU for the whole delay, which is at least 15 minutes on General Purpose and 60 by default. Microsoft names open sessions as the most common reason it never fires. Some features block pausing outright: geo-replication and failover groups, long-term backup retention, and a DNS alias on the server. Others keep waking the database up, including a login, viewing audit records or sensitivity labels, vulnerability assessment scans, and changing a tag. A monitoring tool that polls every ten minutes can keep a serverless database online all day.
Check before you switch. If the 14-day query shows activity in most five-minute windows, serverless won't pause and provisioned is cheaper. Your app also needs retry logic: the first connection to a paused database fails with error 40613 while it resumes, which usually takes under a minute.
05Moving off DTU without guessing
The migration
guide gives a rule of thumb: every 100 DTUs in Basic or Standard need
at least 1 vCore, and every 125 in Premium need at least 1.
Basic and Standard map to General Purpose, Premium to Business Critical. The
same page has a T-SQL query that reads the actual logical CPUs and memory
behind a DTU database. Use it rather than the rule. For an S0 it finds a quarter
of a core: even GP_Gen5_2 is more than that, and serverless
GP_S_Gen5_1 is the closer match.
The change is online, with a short disconnect at the end, and you can move back to DTU later unless you went to Hyperscale. Two serverless limits to size against: concurrent workers are capped at 75% of the provisioned limit for the same max vCores, and memory at 3 GB per max vCore, which is less than provisioned gives. If the database you're right-sizing is steady enough to reserve, the trade-offs are in reservations vs on-demand. Just remember that reservations don't cover serverless.
Utilisation lives in the database. Cost lives in the bill. GraphPaaS reads the bill: the Azure view of Bills shows what each database cost, month by month, across every subscription and every tenant you manage. Azure Advisor's cost recommendations sit next to your idle resources. Start with the most expensive databases, then run the query above on them. Our Azure cost drill-down walks through finding them.
- Compare vCore and DTU-based purchasing models — what each model bills, storage in the DTU, Hybrid Benefit on vCore.
- Serverless compute tier billing — the per-second formula, minimum compute bill, the 24-hour example, no AHB or reservations.
- Auto-pause and auto-resume — pause conditions, features that block it, resume triggers, error 40613.
- Migrate from DTU to vCore — 100/125 DTU rule, the mapping query, the S0 example, serverless worker and memory limits.
- sys.resource_stats — five-minute rows, about 14 days, gaps for idle databases.
- Azure Monitor Metrics overview — 93-day retention, 30 days per chart.
See what every database costs.
Month by month, in every subscription and every tenant you manage.
See your Azure costs by resourceOr ask Claude: "Which SQL databases cost the most each month across our subscriptions?"