Cost Optimisation Strategies in Azure
Cloud cost optimisation is not a one-time event — it is an ongoing practice of matching your spending to your actual needs. Azure provides extensive tooling for visibility, analysis, and automation, but the tooling only works if you have the right organisational habits: tagging resources for cost attribution, reviewing spending regularly, and giving engineering teams the data they need to make cost-conscious decisions. This page covers the most impactful optimisation strategies, how to implement them, and how to build a governance model that keeps costs under control as your environment grows.
Getting visibility first
You cannot optimise what you cannot see. Before attempting any cost reduction, invest two to four weeks in establishing cost visibility across your Azure environment.
Azure Cost Management + Billing provides cost analysis, budget alerts, and an advisor with specific recommendations. Navigate to the Cost Management blade in the Azure portal and enable the Cost Analysis view. Filter by subscription, resource group, service, and tag to understand where money is being spent.
Tagging is the foundation of cost attribution. Every resource should have at minimum a cost-centre, environment, and team tag. Enforce tags with Azure Policy so that resources cannot be created without them. Once tags are present, Cost Management can split costs by cost centre or team in a single view.
# Apply a cost-centre tag to all resources in a resource group
az tag update \
--resource-id /subscriptions/SUB_ID/resourceGroups/myRG \
--operation merge \
--tags cost-centre=engineering environment=production team=platform
# Create an Azure Policy to enforce required tags
az policy definition create \
--name require-cost-tags \
--display-name "Require cost-centre, environment, and team tags" \
--rules '{
"if": {
"anyOf": [
{"field": "tags[cost-centre]", "exists": false},
{"field": "tags[environment]", "exists": false},
{"field": "tags[team]", "exists": false}
]
},
"then": {"effect": "deny"}
}' \
--mode IndexedRight-sizing compute
The single largest source of waste in most Azure subscriptions is over-provisioned VMs. It is common to see production workloads running on Standard_D8s_v3 (8 vCPUs, 32 GB RAM) where the workload rarely exceeds 15% CPU and 8 GB RAM. Downsizing to Standard_D2s_v3 (2 vCPUs, 8 GB RAM) would reduce the cost by 75%.
Azure Advisor’s “Cost” recommendations tab surfaces VMs whose 7-day average CPU utilisation is below a configurable threshold (default 5%). Review these recommendations and right-size or shut down underutilised VMs. For managed services (App Service plans, Azure Kubernetes Service node pools), check the plan utilisation metrics and downgrade the SKU if headroom is consistently large.
# Get Advisor cost recommendations for a subscription
az advisor recommendation list \
--category Cost \
--query "[?impactedField=='Microsoft.Compute/virtualMachines'].{Resource:impactedValue, Impact:impact, Savings:extendedProperties.annualSavingsAmount}" \
--output table
# Resize a VM to a smaller SKU (requires stopping the VM first)
az vm deallocate --resource-group myRG --name my-vm
az vm resize --resource-group myRG --name my-vm --size Standard_D2s_v3
az vm start --resource-group myRG --name my-vmReserved Instances and Savings Plans
Reserved Instances (RIs) are a billing commitment: you agree to use a specific VM family in a specific region for 1 or 3 years, and Azure charges you a significantly lower hourly rate. You are not locking yourself into a single VM — you can exchange reservations and they apply automatically to any running VM that matches the scope. Reservations are appropriate for any workload that runs continuously: production databases, web servers, application servers.
Azure Savings Plans are more flexible — they commit to a spending level per hour across compute services (VMs, Container Instances, Azure Functions Premium plan) regardless of family or region. Savings Plans offer lower discounts than RIs (around 15–35%) but are appropriate when your workload mix varies significantly over time.
Purchase reservations based on your lowest baseline usage, not your peak. If your environment runs 8 VMs at minimum and scales up to 20, buy 8 RIs. The remaining 12 instances pay on-demand rates, which is correct — you want the on-demand flexibility for variable capacity.
| Commitment Type | Typical Discount | Flexibility | Best For |
|---|---|---|---|
| Pay-As-You-Go | 0% | Full — no commitment | Variable or short-lived workloads |
| Azure Savings Plans (1yr) | 15–25% | Any compute in any region | Flexible but stable spend baseline |
| Reserved Instance (1yr) | 40–45% | Exchangeable within VM family | Stable workloads in a known region |
| Reserved Instance (3yr) | 60–72% | Limited — fewer exchanges | Long-lived, very stable workloads |
| Azure Hybrid Benefit + RI | Up to 82% | As above | Windows/SQL workloads with SA licences |
Autoscaling to eliminate idle capacity
Many workloads have pronounced traffic patterns: heavy during business hours, light overnight and on weekends. Running at full peak capacity 24/7 wastes 60–70% of compute spend on capacity that is idle most of the time. Autoscaling dynamically adjusts the number of instances to match actual demand.
Configure autoscale with a schedule-based rule for predictable patterns and a metric-based rule to handle unexpected spikes. The schedule rule scales out before anticipated peak load (avoiding the 5-minute autoscale lag) and scales in after it subsides. The metric rule catches unscheduled traffic spikes.
# Schedule-based scale-out for business hours (weekdays, 8am-6pm UTC)
az monitor autoscale rule create \
--resource-group myRG \
--autoscale-name myAutoscale \
--scale to 8 \
--condition "Percentage CPU > 0 avg 1m"
# Schedule to scale down overnight
az monitor autoscale profile create \
--resource-group myRG \
--autoscale-name myAutoscale \
--name night-profile \
--count 2 \
--min-count 2 \
--max-count 4 \
--recurrence-days Monday Tuesday Wednesday Thursday Friday \
--recurrence-hours 20 \
--recurrence-mins 0 \
--timezone "UTC"For development and test environments, use Azure Dev/Test pricing (available through Visual Studio subscriptions) and schedule VMs to shut down entirely overnight and on weekends. A VM that runs 12 hours a day on weekdays costs 30% of its always-on equivalent.
Storage tiering and lifecycle management
Azure Blob Storage offers four access tiers: Hot (immediate access, highest storage cost), Cool (infrequent access, lower storage cost, access fee per operation), Cold (rare access, very low storage cost), and Archive (near-zero storage cost, several hours to rehydrate). Data that starts in the Hot tier should migrate to cooler tiers as it ages.
Blob lifecycle management policies automate this migration. Define a policy that moves blobs older than 30 days to Cool, older than 90 days to Cold, and older than 365 days to Archive. For a typical log storage workload, this can reduce storage costs by 70–80% with no manual intervention.
{
"rules": [
{
"name": "lifecycle-rule",
"enabled": true,
"type": "Lifecycle",
"definition": {
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["logs/"]
},
"actions": {
"baseBlob": {
"tierToCool": {"daysAfterModificationGreaterThan": 30},
"tierToCold": {"daysAfterModificationGreaterThan": 90},
"tierToArchive": {"daysAfterModificationGreaterThan": 365},
"delete": {"daysAfterModificationGreaterThan": 2555}
}
}
}
}
]
}Budgets and anomaly alerts
Azure Cost Management budgets define spending thresholds that trigger email or action group alerts. Set a budget for each subscription and for important resource groups. Configure alerts at 80% of budget (warning) and 100% of budget (action required). Action groups can trigger an Azure Function or Logic App that automatically suspends non-critical workloads when a budget is exceeded.
Cost anomaly detection in Azure Cost Management uses machine learning to identify unexpected spending changes. It sends daily emails when it detects a cost pattern significantly outside normal bounds — useful for catching accidental resource creation, runaway autoscale, or an expensive API call being made unexpectedly often.
Common mistakes
- Buying Reserved Instances before establishing stable baselines. If you buy 20 RIs for a workload that you subsequently migrate to a different VM family, you may be stuck with reservations that do not apply. Wait until a workload has been running stably for 3+ months before committing to reserved capacity, and use the Azure Cost Management reservation recommendations which analyse your actual usage patterns.
- Ignoring unattached disk costs. When a VM is deleted, its data disk is not automatically deleted. Orphaned managed disks accumulate silently and can represent significant spend. Run a monthly query to list all disks with no ownerVM tag and review them for deletion.
- Using Premium SSD for all disks by default. Many non-critical disks do not require the IOPS of Premium SSD. Standard SSD at 60–70% lower cost is appropriate for development VMs, log disks, and data disks with low IOPS requirements. Review disk SKUs as part of right-sizing exercises.
Summary
- Establish tag-based cost attribution before optimising — you cannot cut what you cannot see.
- Right-size VMs using Azure Advisor recommendations; oversized compute is the most common source of waste.
- Purchase Reserved Instances for stable baseline workloads; pair with Azure Hybrid Benefit for Windows and SQL workloads.
- Configure autoscale for variable workloads and schedule dev/test environments to shut down outside business hours.
- Apply Blob Storage lifecycle policies to automatically move ageing data to cheaper access tiers.
- Set budget alerts and enable anomaly detection to catch unexpected spend early.
Frequently asked questions
How much can I save with Reserved Instances vs Pay-As-You-Go?
Azure Reserved VM Instances offer discounts of 40–72% compared to pay-as-you-go pricing, depending on the VM family, region, and whether you pay upfront or monthly. One-year reservations typically save 40–45%; three-year reservations typically save 60–72%. Reserved capacity is available for SQL Database, App Service, Azure Cache for Redis, and other services as well, each with their own discount tiers.
What is the Azure Hybrid Benefit and who can use it?
Azure Hybrid Benefit lets you apply your existing on-premises Windows Server and SQL Server licenses (covered by Software Assurance or available as subscription licences) to Azure VMs and Azure SQL, significantly reducing the compute cost. On Windows VMs it eliminates the Windows Server license fee. On SQL Azure it can reduce SQL Database costs by up to 55%. It is available to all customers with eligible licenses.
How do I identify unused resources in Azure?
Azure Advisor surfaces recommendations for underutilised VMs, unattached disks, unused public IP addresses, and idle load balancers. Azure Cost Management provides a recommendation engine as well. For programmatic discovery, query Azure Resource Graph for disks with no associated VM, NICs with no associated VM, and public IPs with no associated resource. Run this query monthly and delete or downgrade resources with zero recent usage.