Azure cost optimization works best as a repeatable review rather than a one-time cleanup. This checklist shows how to audit virtual machines, disks, storage, databases, and idle resources; compare savings options; estimate monthly impact; and document decisions so the process can be repeated at every billing cycle.
Overview
An Azure bill is usually the result of several independent choices: compute capacity, storage volume, transaction activity, data transfer, licensing, backup retention, and the number of resources that remain deployed. A useful Azure cost management guide therefore starts with actual usage and billing data, not with a blanket instruction to choose the cheapest service.
Begin in Cost Management at the billing-account, subscription, or resource-group scope that you manage. Review the previous complete billing period and compare it with at least one earlier period. Group costs by service name, resource, resource group, region, and tags. This reveals whether growth comes from a single virtual machine, a shared platform service, or a broad increase in consumption.
Use the following monthly Azure cost optimization checklist:
- Confirm that the scope includes every subscription used by the workload.
- Group spending by resource and service, then identify the largest changes.
- Check virtual machines for low utilization, oversized disks, unattached disks, and unnecessary public IPs.
- Review storage accounts for old data, replication settings, snapshots, versions, and transaction-heavy workloads.
- Review databases for capacity, tier, provisioned throughput, backup retention, and nonproduction schedules.
- Search for resources that are stopped, disconnected, empty, duplicated, or no longer associated with an owner.
- Compare pay-as-you-go spending with eligible commitment options only after usage is stable.
- Record the owner, expected saving, operational risk, and rollback plan for every change.
Do not treat a lower invoice as the only success measure. A change that saves money but causes performance problems, weakens recovery, or creates manual work may not be a good optimization.
How to estimate
Use a simple baseline-and-scenario model. For each resource or workload, record:
- Baseline monthly cost: the actual cost for a complete billing period.
- Expected usage: hours, storage quantity, requests, throughput, or database capacity.
- Proposed configuration: the target size, tier, schedule, redundancy, or commitment.
- Scenario cost: the estimated cost after the change using current pricing information for the selected region, currency, agreement, and billing model.
- Net saving: baseline cost minus scenario cost, including any migration, licensing, or operational expense.
A useful formula is:
Estimated monthly saving = current monthly cost − projected monthly cost − one-time monthly-equivalent costs
For example, if a development VM runs continuously but only needs to be available during a weekday schedule, estimate the hours it will actually run rather than assuming a fixed percentage reduction. Validate the schedule against deployment pipelines, patching, backups, and users in other time zones. A stopped VM may still incur charges for attached disks, reserved public IP addresses, or other associated resources.
For repeatable analysis, create a Cost Management view with these dimensions:
- Time grain: monthly for budget reporting; daily when investigating a sudden change.
- Grouping: resource, resource group, service name, and meter where available.
- Filters: subscription, region, environment tag, application tag, and charge type.
- Comparison: current period versus the previous complete period, avoiding partial-month conclusions.
For larger environments, export cost data to a storage account or analytics destination and join it with an inventory of resources. This makes it easier to find resources with cost but no owner, or resources with a production tag that are rarely used.
Example investigation queries and views include:
- VM cost query: filter the cost dataset to the Virtual Machines service, group by resource ID, and compare daily cost with the VM's average CPU and memory utilization.
- Storage query: group by storage account and meter category, then compare capacity, operations, replication, and data-transfer charges.
- Database query: group by database resource and separate compute, storage, backup, and networking-related charges where the dataset exposes them.
- Idle-resource query: list resources with nonzero cost during the selected period, join them to activity or monitoring data, and flag items with no recent owner activity.
These are analysis definitions rather than universal query syntax because available fields vary by export type, agreement, and Azure service. Verify field names in the exported schema before automating them.
Inputs and assumptions
Cost estimates are only as reliable as their inputs. Capture the assumptions beside every recommendation so another administrator can reproduce the calculation.
| Optimization option | Useful input | Trade-off to check |
|---|---|---|
| Resize an Azure VM | CPU, memory, disk throughput, network demand, and peak usage | Performance headroom, restart requirements, and compatibility |
| Schedule nonproduction compute | Required operating hours and dependency schedule | Missed jobs, deployment failures, and delayed testing |
| Remove or consolidate disks | Attachment state, last-write time, snapshots, and recovery needs | Accidental data loss and slower restoration |
| Change storage tier or redundancy | Access frequency, retention, retrieval volume, and recovery objectives | Retrieval charges, availability, and recovery time |
| Change database capacity | Query latency, throughput, connections, and peak workload | Throttling, maintenance impact, and application changes |
| Buy a commitment | Stable eligible usage, term, scope, and payment preference | Unused commitment after migration, shutdown, or downsizing |
When comparing Azure reservations with a savings plan, first separate predictable baseline usage from variable usage. A reservation is generally evaluated against a defined eligible resource configuration and scope, while a savings plan is considered against eligible compute usage across supported choices. Microsoft can change eligibility, terms, and portal labels, so confirm the current details in the Azure portal before purchase. Do not commit fluctuating development workloads merely because they were expensive in one month.
Also distinguish a stopped resource from a deallocated resource. The exact billing result depends on the service and associated components. Check the service's current pricing and billing documentation before using an assumed zero-cost rule in a forecast.
Worked examples
Example 1: Development virtual machines
Suppose a development resource group contains several VMs that are available around the clock but are normally used during business hours. First export the last complete month's costs by resource. Then compare the operating schedule with pipeline runs, backup windows, patching, and test requirements. Estimate a schedule-based scenario using the actual planned hours, and separately calculate the continuing cost of disks, IP addresses, monitoring, and backup components.
Before applying the schedule, test it on one noncritical VM. Add an owner tag, an exception process, and an alert when a developer starts the VM outside the normal window. The saving estimate should be reported as a range if usage is not consistent.
Example 2: Storage and managed disks
For storage, compare current capacity and access patterns with the retention policy. Identify old blobs, snapshots, and unattached disks, but do not delete them solely because they are old. Confirm whether they support restore testing, legal retention, disaster recovery, or an active deployment. Model the cost of the target tier together with retrieval, transactions, replication, and data movement. A lower capacity charge may not produce a lower total cost if access is frequent.
Example 3: Database capacity
For a database, chart cost against CPU, storage, latency, connections, and throughput over a representative period. A smaller tier may be appropriate for a quiet development database, while a production database may need capacity for a short but important peak. Test changes outside the busiest period, define a rollback threshold, and compare the post-change bill with performance metrics rather than relying on the configuration name alone.
When to recalculate
Run the complete review after each billing cycle and perform a shorter exception review weekly for fast-growing environments. Recalculate sooner when pricing inputs change, a region changes, a workload is migrated, a VM family or database tier is replaced, storage retention changes, or a reservation or savings plan is approaching renewal.
Keep a dated optimization log with the original cost, selected assumptions, portal recommendation, approval, implementation date, and measured result. Revisit recommendations that have been ignored for several months; the workload may now be stable enough for a commitment, or its requirements may have changed.
Your next action should be practical: choose one subscription, export the previous complete billing period, identify the top five resources by cost change, and assign an owner to each. Apply one low-risk improvement, such as removing a confirmed unattached resource or scheduling a test VM, then compare the next complete period with the baseline. Repeat the same checklist monthly and refresh pricing, reservation rules, and product recommendations at least quarterly.
For storage-specific assumptions, see Azure Storage Pricing Explained. If a sudden increase may be related to a regional incident or service disruption, check the Azure Service Health and Status Guide before changing production capacity.