Azure Cost Optimization â Pricing & Savings Guide
In this tutorial, you'll learn about Azure Cost Optimization. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Azure cost optimization reduces your Microsoft Azure bill by right-sizing virtual machines, leveraging reservations and savings plans, tiering blob storage, minimizing data egress, and enforcing governance with Azure Policy and budgets.
What You'll Learn
By the end of this guide, you'll be able to use Azure Cost Management, right-size VMs with Azure Advisor, choose between Reserved Instances and Savings Plans, tier storage with lifecycle management, reduce data transfer costs, and set up budget alerts and policies.
Why It Matters
Azure costs can spiral as teams spin up resources without governance. Most Azure accounts waste 30-40% on over-provisioned VMs, unattached disks, and unnecessary data egress. A $40k monthly bill can drop to $25k with structured optimization. DodaTech reduced DodaZIP's Azure infrastructure costs by 35% using reservations and right-sizing.
Real-World Use
Adobe uses Azure Cost Management to track spend across 500+ subscriptions. Siemens implemented Azure Policy to enforce tagging and reduced unallocated costs by 50%. Maersk saved 40% on Azure Kubernetes Service by right-sizing node pools.
flowchart LR
A[Cost Management] --> B[Right-Size VMs]
B --> C[Reservations]
B --> D[Spot VMs]
A --> E[Storage Tiering]
A --> F[Azure Policy]
C --> G[30-60% Savings]
style G fill:#0078d4,color:#fff
Prerequisites: Azure subscription access, familiarity with Azure VMs and storage. Understanding of Cloud Computing fundamentals helps.
1. Cost Visibility with Azure Cost Management
Azure Cost Management provides dashboards, budgets, and recommendations across subscriptions.
# Install Azure CLI and query costs
az account list --output table
# View current month costs by resource type
az consumption usage list \
--billing-period-name 202606 \
--query "[].{Service:consumedService, Cost:pretaxCost}" \
--output table
Expected output:
Service Cost
---------------------- --------
Virtual Machines 12,450
Storage 3,800
Bandwidth 2,100
SQL Database 1,900
Azure Kubernetes Service 1,200
2. Right-Sizing Azure VMs
Azure Advisor analyzes VM utilization and recommends right-sizing or shutting down idle VMs.
# Get Advisor right-sizing recommendations
az advisor recommendation list \
--category Cost \
--query "[?impactedField=='Microsoft.Compute/virtualMachines']" \
--output table
# vm_rightsize_analyzer.py
class VMAnalyzer:
def __init__(self):
self.vms = []
def add_vm(self, name, vcpus, ram_gb, cpu_pct, monthly_cost):
self.vms.append({"name": name, "vcpus": vcpus, "ram_gb": ram_gb, "cpu_pct": cpu_pct, "cost": monthly_cost})
def recommend(self):
for vm in self.vms:
if vm["cpu_pct"] < 20:
smaller = max(vm["vcpus"] // 2, 1)
savings = vm["cost"] * 0.4
print(f"{vm['name']}: {vm['vcpus']} vCPU â {smaller} vCPU (CPU={vm['cpu_pct']}%). Save ${savings:.0f}/mo")
elif vm["cpu_pct"] > 80:
print(f"{vm['name']}: Consider scaling up (CPU={vm['cpu_pct']}%)")
analyzer = VMAnalyzer()
analyzer.add_vm("web-prod-1", 8, 32, 12, 520)
analyzer.add_vm("db-prod-1", 16, 64, 8, 980)
analyzer.add_vm("worker-1", 4, 16, 75, 310)
analyzer.recommend()
Expected output:
web-prod-1: 8 vCPU â 4 vCPU (CPU=12%). Save $208/mo
db-prod-1: 16 vCPU â 8 vCPU (CPU=8%). Save $392/mo
3. Azure Reservations and Savings Plans
| Model | Discount | Flexibility |
|---|---|---|
| Reserved VM Instances | 30-72% | Specific region, OS, instance family |
| Azure Savings Plan | 30-65% | Compute across regions and services |
| Reserved Capacity | 20-60% | SQL DB, Cosmos DB, Storage |
# Purchase a Reserved VM Instance
az reservations reservation purchase \
--reservation-order-id "order-123" \
--reserved-resource-type "VirtualMachines" \
--sku "Standard_D2s_v3" \
--location "eastus" \
--quantity 3 \
--term "P1Y" \
--billing-scope "Subscription"
# Check reservation utilization
az reservations reservation list \
--query "[].{Name:name, Utilization:properties.utilization}" \
--output table
Strategy: Reserve baseline at 60-70% with 1-year plans. Use Savings Plans for flexible workloads. Run dev/test on Pay-as-You-Go or Spot.
4. Azure Storage Tiering
Azure Blob Storage offers Hot, Cool, Cold, and Archive tiers:
# Set lifecycle management policy
az storage account management-policy create \
--account-name dodatechstorage \
--policy @lifecycle-policy.json
# lifecycle-policy.json
# {
# "rules": [{
# "name": "tier-logs", "# "enabled": true", "# "type": "Lifecycle"",
# "definition": {
# "filters": {"blobTypes": ["blockBlob"], "prefixMatch": ["logs/"]},
# "actions": {
# "baseBlob": {
# "tierToCool": {"daysAfterModificationGreaterThan": 30},
# "tierToArchive": {"daysAfterModificationGreaterThan": 180},
# "delete": {"daysAfterModificationGreaterThan": 730}
# }
# }
# }
# }]
# }
Cost comparison: Hot = $0.018/GB, Cool = $0.01/GB, Cold = $0.0045/GB, Archive = $0.00099/GB. Tiering 10TB from Hot to Cool saves $80/month.
5. Data Transfer and Egress
Azure egress costs $0.087/GB (internet), $0.02/GB (cross-region). Use these strategies:
# azure_egress_audit.py
services = {
"Internet egress": {"gb": 5000, "rate": 0.087},
"Cross-region": {"gb": 8000, "rate": 0.02},
"Azure CDN": {"gb": 5000, "rate": 0.084},
"ExpressRoute": {"fixed": 150, "gb": 10000, "rate": 0.01},
}
for name, s in services.items():
cost = s.get("fixed", 0) + s["gb"] * s["rate"]
print(f"{name:<20} ${cost:>8.2f}/mo")
print(f"{'TOTAL':<20} ${sum(s.get('fixed',0) + s['gb']*s['rate'] for s in services.values()):>8.2f}/mo")
Expected output:
Internet egress $435.00/mo
Cross-region $160.00/mo
Azure CDN $420.00/mo
ExpressRoute $250.00/mo
TOTAL $1265.00/mo
6. Azure Policy and Budgets
Enforce tagging and cost governance with Azure Policy:
# Assign a built-in policy to require tags
az policy assignment create \
--name "require-cost-center-tag" \
--policy "2a0e14d6-b0a9-4a6a-9a3f-8f5b3f1a2c3d" \
--params '{"tagName":"CostCenter"}' \
--scope "/subscriptions/your-sub-id"
# Create a budget with email alerts
az consumption budget create \
--budget-name "monthly-compute" \
--amount 15000 \
--time-grain "Monthly" \
--category "Cost" \
--scope "/subscriptions/your-sub-id" \
--notifications '{
"Alert1": {"enabled": true, "operator": "GreaterThan", "threshold": 80, "contact-emails": ["finops"@example".com"]}
}'
Common Mistakes
1. No Azure Policy Governance
Without policies, teams provision resources without tagging, making cost allocation impossible. Always enforce minimum tags at subscription level.
2. Ignoring Hybrid Benefit
If you have on-premises Windows Server or SQL Server licenses, use Azure Hybrid Benefit to save up to 40% on VM and SQL costs.
3. Unattached Managed Disks
Deleting a VM doesn't delete its OS disk. Use az disk list --query "[?managedBy==null]" to find and clean unattached disks.
4. Over-Provisioned Premium SSD
Most workloads don't need Premium SSD. Use Standard SSD or HDD for dev/test and non-critical workloads. Premium SSD costs 4x more.
5. No Auto-Shutdown for Dev/Test
Dev VMs running 24/7 at $200/month cost $2,400/year. Implement auto-shutdown schedules to run only during business hours.
Practice Questions
1. What is the difference between Azure Reservations and Azure Savings Plan? Reservations lock to a specific VM SKU and region. Savings Plans apply to any compute across regions and services. Savings Plans offer more flexibility at slightly lower discounts.
2. How does Azure Hybrid Benefit work? It lets you use on-premises Windows Server and SQL Server licenses with Software Assurance on Azure VMs, reducing licensing costs by up to 40%.
3. What are the Azure Blob Storage access tiers? Hot (frequent access), Cool (infrequent, 30+ days), Cold (rare, 90+ days), Archive (offline, 180+ days). Each tier trades lower storage cost for higher access cost.
4. Challenge: Optimize a $60k/month Azure subscription: analyze Cost Management data, right-size all VMs, purchase reservations for baseline, implement lifecycle policies for all storage accounts, enforce tagging with Azure Policy, and set up budget alerts.
Mini Project: Azure Cost Optimizer CLI
class AzureCostOptimizer:
def __init__(self, monthly_budget):
self.budget = monthly_budget
self.recommendations = []
def check_vm_rightsizing(self, vms):
for vm in vms:
if vm["cpu_pct"] < 15:
self.recommendations.append(f"Downsize {vm['name']} ({vm['cpu_pct']}% CPU)")
if vm["attached_disks"] == 0:
self.recommendations.append(f"Delete unattached disks for {vm['name']}")
def check_reservation_coverage(self, on_demand_cost):
coverage = on_demand_cost / self.budget * 100
if coverage > 30:
self.recommendations.append(f"Cover {coverage:.0f}% of on-demand spend with Reservations")
def report(self):
print(f"=== Azure Cost Optimizer ===")
print(f"Monthly budget: ${self.budget:,}")
print(f"Recommendations ({len(self.recommendations)}):")
for r in self.recommendations:
print(f" âĸ {r}")
opt = AzureCostOptimizer(40000)
opt.check_vm_rightsizing([
{"name": "web-1", "cpu_pct": 8, "attached_disks": 1},
{"name": "db-1", "cpu_pct": 60, "attached_disks": 5},
])
opt.check_reservation_coverage(15000)
opt.report()
FAQ
Related Concepts
What's Next
You now understand Azure cost optimization! Next, learn about GCP Cost optimization, then explore Multi-Cloud Cost optimization for managing costs across Azure, AWS, and GCP.
- Practice daily â Review your Azure Cost Management dashboards
- Build a project â Automate unattached disk cleanup with Azure Automation
- Explore related topics â Check out Azure Reservations vs Savings Plans deep dive
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro