Cost Optimization

    How Do You Optimize Azure Virtual Machines Across Cost, Security, Performance, and Reliability?

    Optimize Azure VMs across all five Well-Architected Framework pillars — from deallocating stopped VMs and right-sizing compute to hardening security, enabling backup, and retiring legacy agents.

    Spotto
    February 2026
    35 min read

    Azure Virtual Machines are usually the single largest line item on an Azure invoice -- and also where the most optimization opportunities hide in plain sight. A comprehensive VM optimization strategy works across five dimensions at once: eliminating compute waste through right-sizing and deallocation, aligning disk tiers with actual I/O demand, hardening security by removing public exposure and closing patch gaps, protecting business continuity with zone-redundant deployments and validated backups, and retiring legacy agents and end-of-life operating systems before they become liabilities.

    Spotto's continuous analysis across all five Well-Architected Framework pillars surfaces these opportunities automatically -- flagging stopped-but-allocated VMs still burning compute budget, Premium SSDs running at 5% of provisioned IOPS, machines with 95%+ CPU saturation headed for an outage, and publicly exposed endpoints that have no business being on the internet. The result is a fleet that costs less, performs better, and passes audits without scrambling.

    Key Takeaways at a Glance:

    Deallocate stopped VMs for 70-80% compute savings (low risk)
    Downsize oversized VMs for 30-50% compute savings (medium risk)
    Downgrade idle Premium disks for 40-60% storage savings (medium risk)
    Switch Intel to AMD for ~10% compute savings (medium risk)
    Adopt Spot for burst workloads for 60-90% compute savings (medium risk)
    Migrate MMA to AMA for 20-40% log ingestion savings
    Remove public IPs to eliminate 90%+ of attack surface
    Deploy to Availability Zones for 99.99% SLA (up from 99.9%)

    What Problem This Solves

    Most Azure VM fleets accumulate inefficiency gradually. A VM gets provisioned for a migration, sized generously "just in case," and never revisited. A Premium SSD gets attached because someone copied a template. A public IP gets assigned for a quick test and stays forever. Multiply that across hundreds or thousands of VMs managed by an MSP, and the waste compounds:

    Compute overspend — VMs running at 10-15% CPU utilization cost the same as VMs running at 70%. Right-sizing a single D8s_v5 from 8 to 4 vCPUs saves around $280/month. Across 200 oversized VMs, that is $56,000/month in recoverable spend.
    Storage misalignment — Premium SSD OS disks provisioned for workloads that generate 50 IOPS cost 40-60% more than Standard SSDs that would perform identically for that workload.
    Security exposure — A VM with a public IP and permissive NSG rules appears in internet-wide scans within minutes of deployment. Automated brute-force attacks follow within hours.
    Reliability gaps — A VM without backup protection is one ransomware event away from a full rebuild measured in days, not hours. A VM outside an Availability Zone forfeits the 99.99% SLA and concentrates risk in a single fault domain.
    Operational debt — Legacy monitoring agents inflate log ingestion costs by 20-40% while blocking access to modern Azure Monitor features. End-of-life operating systems accumulate unpatched CVEs with no vendor fix available.

    For Managed Service Providers managing multiple tenants via Azure Lighthouse, these issues multiply across every customer environment. Without continuous, automated detection, optimization becomes a quarterly fire drill rather than a standing practice.

    30 Recommendations Across 5 Well-Architected Framework Pillars
    ──────────────────────────────────────────────────────────────────────
      COST (10)             PERFORMANCE (6)       SECURITY (5)
      ├─ Stopped VMs        ├─ CPU critical        ├─ Public IP exposure
      ├─ CPU oversized      ├─ CPU high            ├─ Public access risk
      ├─ Memory oversized   ├─ CPU low/oversized   ├─ Network anomalies
      ├─ Intel → AMD        ├─ Memory high         ├─ Guest non-compliant
      ├─ Spot instances     ├─ Memory low          └─ OS patching gaps
      ├─ Disk downgrades(4) └─ Size optimization
      ├─ Disk upgrades (2)    RELIABILITY (4)      OPS EXCELLENCE (5)
      └─ MMA → AMA            ├─ No backup          ├─ Large OS disk
                               ├─ Stale backup       ├─ OS end-of-life
                               ├─ No Avail. Zones    ├─ SQL end-of-life
                               └─ No Site Recovery    ├─ SQL disk layout
                                                      └─ SQL disk caching

    Azure VM SLA Quick Reference

    Before diving into optimization actions, here is the SLA baseline that drives many of these decisions:

    Deployment ModelSLAMonthly Downtime
    Single Instance (Standard HDD)95.0%~36 hours
    Single Instance (Standard SSD)99.5%~3.6 hours
    Single Instance (Premium SSD / Ultra)99.9%~43 minutes
    Availability Set (2+ VMs)99.95%~22 minutes
    Availability Zones (2+ VMs, 2+ zones)99.99%~4.3 minutes

    Note: Single-instance SLA is determined by the lowest-tier disk attached. One Standard HDD data disk drops the entire VM to 95%.

    How It Works

    Right-Sizing and Compute Cost Optimization: Matching Capacity to Demand

    Are your VMs sized for what they actually do, or for what someone imagined they might do two years ago? Azure VM right-sizing is the highest-impact, lowest-risk cloud cost optimization for most VM fleets. It addresses six distinct patterns of compute waste.

    Deallocate Stopped VMs

    A VM in the "Stopped (allocated)" state continues to reserve host capacity and incur full compute charges -- identical to a running VM. It is essentially paying rent on an apartment nobody lives in. This is the easiest cost recovery in Azure:

    Detection — Identify VMs in PowerState/stopped (not PowerState/deallocated) via Azure Resource Graph
    Savings — 70-80% of VM cost eliminated immediately (managed disks, static IPs, and backup policies continue billing)
    Risk — VMs with ephemeral OS disks lose their OS state on deallocation; dynamic public IPs change on restart
    Automation — Schedule auto-shutdown via Azure DevTest Labs policies or Azure Automation runbooks
    # Find all stopped-but-allocated VMs across subscriptions
    Search-AzGraph -Query @"
    resources
    | where type == 'microsoft.compute/virtualmachines'
    | where properties.extended.instanceView.powerState.code == 'PowerState/stopped'
    | project name, resourceGroup, subscriptionId, location
    "@
    ChargeStopped (Allocated)Stopped (Deallocated)
    Triggered byGuest OS shutdownPortal / CLI / PS
    Compute chargesYES (full rate)NO
    Managed disksYESYES
    Static public IPsYESYES
    Host reservationRetainedReleased
    IP addressRetainedMay change (dynamic)

    As of June 2025, Azure enforces a minimum 5-minute billing duration per VM start. Starting and immediately stopping a VM incurs 5 minutes of compute charges.

    Downsize Oversized VMs (Low CPU and Memory)

    VMs with sustained CPU utilization below 20% or available memory above 70% for 95% of the past 30 days are likely oversized:

    CPU-based right-sizing — Reduce vCPU count to align the 95th percentile utilization to 50-70% headroom
    Memory-based right-sizing — Reduce RAM to leave 20-30% free at the 95th percentile
    Typical savings — 30-50% per VM when dropping one or two size tiers

    Considerations before resizing: Confirm headroom is not reserved for seasonal peaks, DR failover, or batch jobs. Check application-level memory reservations (SQL Server buffer pools, JVM heap, Redis maxmemory). Verify the target SKU preserves required NIC count, disk count, and accelerated networking. Resize requires VM deallocation -- schedule during maintenance windows.

    Switch from Intel to AMD

    AMD EPYC-based VMs (Dasv5 series) offer approximately 10% lower on-demand pricing than Intel equivalents (Dsv5 series) at comparable performance:

    SeriesProcessor$/hr$/monthSavings
    D8s v5Intel Xeon$0.384$280baseline
    D8as v5AMD EPYC$0.344$251~10%

    On Spot pricing, the AMD advantage widens to ~24%. Blockers to check: AVX-512 dependency, Intel SGX requirements, per-socket licensing tied to specific processor vendors, and region availability for AMD SKUs.

    Adopt Spot Instances for Interruptible Workloads

    Azure Spot VMs offer 60-90% discounts over on-demand pricing for workloads that can tolerate interruption:

    Eviction notice — Approximately 30 seconds via IMDS Scheduled Events API
    Best candidates — Batch processing, CI/CD build agents, rendering, dev/test, stateless web tier behind a load balancer
    Tip — Set max price to -1 to avoid price-based eviction (only capacity-based). Microsoft reports over 90% of Spot workloads complete before eviction

    Disk Performance and Storage Cost: Matching Tier to I/O Reality

    Are you paying Premium prices for Standard workloads, or throttling Standard disks on Premium workloads? Azure disk cost optimization has two directions: downgrade over-provisioned disks to save money, or upgrade throttled disks to fix performance.

    Downgrade Under-Utilized Premium and SSD Disks

    Premium SSD disks running at a small fraction of provisioned IOPS represent pure waste. Data disks and OS disks with consistently low IOPS utilization (below 20% of provisioned capacity) can be downgraded to smaller Premium SKUs or Standard SSD for 30-60% savings.

    FeaturePremium SSD (P-series)Standard SSD (E-series)
    Max IOPS (P30/E30)5,000500
    Max throughput200 MB/s60 MB/s
    Single-instance SLA99.9%99.5%
    Cost (256 GiB)~$38.40/month~$19.20/month
    Best forProduction, I/O-heavyDev/test, low-I/O prod

    If your Premium disk uses less than 500 IOPS consistently, Standard SSD delivers the same performance at roughly half the price.

    Upgrade Throttled Disks

    Disks consistently hitting IOPS or throughput limits cause storage throttling that cascades into application latency. Upgrade options include increasing Premium SSD size (P30 to P40 doubles IOPS from 5,000 to 7,500), Premium SSD v2 for variable demand, or Ultra Disk for extreme I/O (up to 160,000 IOPS, sub-millisecond latency).

    Performance Under Pressure: Detecting Saturation Before It Becomes an Outage

    CPU Saturation (Critical and High)

    Utilization LevelSignalRecommended Action
    < 20% (30-day P95)Over-provisionedRight-size down
    20-70% (30-day P95)Healthy headroomMonitor, no action
    70-90% (30-day P95)ElevatedPlan proactive resize
    > 95% (sustained)Critical saturationScale up/out urgently

    Before scaling up, rule out runaway processes or memory leaks consuming CPU, misconfigured thread pools or connection limits, and cron jobs or scheduled tasks that overlap with peak hours.

    Memory Pressure

    Low available memory manifests as kernel paging, garbage collection thrashing, and out-of-memory kills. Before scaling, confirm whether high utilization is intentional (database buffer pools, in-memory caches are supposed to use most of available RAM) and investigate for memory leaks before throwing hardware at the problem. If scaling is needed, memory-optimized SKUs (Esv5 series) provide more RAM per vCPU. Target 20-30% free memory at the 95th percentile as operating headroom.

    Security and Attack Surface: Reducing Exposure Before Attackers Find It

    How many of your VMs are directly reachable from the internet right now -- and how many of those should be? If you manage Azure infrastructure for multiple customers, the honest answer is probably "more than you think."

    Remove Unnecessary Public Exposure

    Risk LevelConfigurationTime to First Attack
    CRITICALPublic IP + open RDP/SSH (0.0.0.0)Minutes
    HIGHPublic IP + restricted portsHours
    MODERATEPublic IP + NSG allowlistDays (port scanning)
    LOWPrivate IP + Bastion/VPN onlyRequires internal access
    MINIMALPrivate IP + NSG + no public routeLateral movement only

    Remediation path:

    Administration access — Replace public IP + NSG with Azure Bastion (Basic ~$139/month, Standard ~$212/month)
    Application traffic — Route through Application Gateway, Azure Front Door, or reverse proxy
    Outbound-only access — Use NAT Gateway instead of per-VM public IPs
    If public IP must remain — Restrict to known source IPs, enable DDoS Protection Standard, enable JIT VM access

    Close Patch and Compliance Gaps

    Outdated OS patching (90+ days) — Known CVEs are actively exploited in the wild within days of disclosure. Use Azure Update Manager with staged rollout and backup validation.
    Guest configuration non-compliant — In-guest settings have drifted from the approved baseline. Remediate through Azure Policy Guest Configuration with change control.

    Both issues breach PCI DSS, SOC 2, ISO 27001, and CIS benchmark requirements. Auditors flag these as high-severity findings.

    Reliability and Business Continuity

    When was the last time you tested a restore from backup? If the answer takes more than two seconds, that is the problem.

    Enable Azure Backup

    Without Backup

    Recovery time: Days to weeks

    Data loss: Since last manual copy

    Ransomware defense: None

    Effort: Full rebuild from docs

    Cost: $0

    With Azure Backup

    Recovery time: Hours

    Data loss: Since last recovery point

    Ransomware defense: Soft delete + immutable

    Effort: Point-in-time restore

    Cost: ~$0.05/GB/month (GRS)

    Deploy to Availability Zones

    Without zones — 99.9% SLA (single instance with Premium SSD) or 99.95% (Availability Set)
    With zones — 99.99% SLA (2+ VMs across 2+ zones with zone-redundant load balancer)
    Migration path — Requires VM redeployment -- this is not a live migration

    Enable Azure Site Recovery

    VMs without cross-region disaster recovery depend on manual rebuilds from backup after a regional outage. ASR provides automated failover in minutes with RPO measured in configured replication intervals, at ~$25/month per protected instance (first 31 days free).

    Lifecycle and Monitoring: Retiring Technical Debt

    Migrate from MMA to Azure Monitor Agent (AMA)

    The Microsoft Monitoring Agent (MMA/OMS) was officially retired on August 31, 2024. VMs still running MMA face higher ingestion costs, feature gaps, and increasing stability risk.

    CapabilityMMA (Retired)AMA (Current)
    Source-side filteringNo (send all)Yes (via DCRs)
    Private LinkNoYes
    Configuration methodWorkspace-basedData Collection Rules
    Cost impactHigher ingestion20-40% lower ingestion
    Auto-updateNoYes

    Address End-of-Life Operating Systems and SQL Server

    VMs running OS versions past mainstream support no longer receive security patches. The same risk applies to SQL Server versions past mainstream support. Validate application compatibility in a non-production environment before upgrading, and check whether Extended Security Updates are available as a temporary measure.

    SQL Server on VMs: Storage Architecture and Caching

    SQL Server disk misconfiguration is one of the most common -- and most fixable -- performance problems in Azure VM environments.

    RoleDisk TypeCachingNotes
    OSStandard SSDReadWriteDefault, adequate for OS
    DataPremium SSDReadOnlyStriped pool for large DBs
    LogPremium SSDNoneWrite-ordering critical
    TempDBLocal SSD / PremiumNoneStartup script if local
    BackupStandard HDDNoneCost-optimized, sequential

    Important: Ultra Disk and Premium SSD v2 do not support host caching. Clustered/shared disks must use None.

    Cost Impact Summary

    OptimizationTypical SavingsComplexity
    Deallocate stopped VMs70-80% per VMLow
    Downsize oversized VMs (CPU/memory)30-50% per VMMedium
    Switch Intel to AMD~10% per VMMedium
    Adopt Spot for interruptible workloads60-90% per VMMedium
    Downgrade Premium SSD to Standard SSD40-60% per diskMedium
    Migrate MMA to AMA (log ingestion)20-40% on logsMedium
    Remove unnecessary public IPs$3.65/month eachLow

    Aggregate: A fleet of 200 VMs with typical inefficiencies can recover $30,000-$80,000/month through systematic optimization.

    Use-Case and Scenario Coverage

    Scenario 1: MSP Managing 15 Customer Tenants via Azure Lighthouse

    Initial state

    800+ VMs across tenants, no standardized optimization

    Outcome

    $53,000/month recovered

    45 stopped-allocated VMs ($18,000/month waste) deallocated immediately. Right-sizing and disk downgrades recovered an additional $35,000/month over 90 days.

    Scenario 2: Dev/Test Environment Cost Control

    Before

    $42,000/mo

    60 developer VMs running 24/7 on D4s_v5 with Premium SSD

    After

    $11,000/mo

    Auto-shutdown, burstable VMs, Standard SSD

    74% reduction -- $372,000/year

    Scenario 3: SQL Server Workload on IaaS VMs

    10 SQL Server VMs with data, logs, and tempdb on a single P30 disk per VM. Disk caching set to ReadWrite on all disks including log volumes.

    Outcome: SQL query throughput improves 40-60%. WRITELOG waits drop by 70%. Backup windows shorten from 4 hours to 90 minutes due to smaller OS disk snapshots.

    Scenario 4: SaaS Platform Running on Azure VMs

    Before

    $120,000/mo

    30 D16s_v5 VMs, all running 24/7 on Premium SSD

    After

    $45,000/mo

    Spot instances, AMD migration, scheduled scaling

    62% reduction -- $900,000/year

    Recommended Rollout Sequence

    Week 1 -- Quick wins (no application risk) — Deallocate all stopped-allocated VMs, remove unnecessary public IPs, enable backup on unprotected VMs
    Week 2-4 -- Storage optimization — Downgrade under-utilized Premium disks, upgrade throttled disks, separate SQL Server disk layouts
    Month 2 -- Compute right-sizing — Right-size oversized VMs based on 4-6 weeks of telemetry, evaluate AMD migration, deploy Spot instances
    Month 3 -- Reliability and lifecycle — Migrate to Availability Zones, enable ASR, complete MMA-to-AMA migration, begin OS/SQL end-of-life remediation

    Automation: Weekly VM Fleet Health Check

    # Weekly Azure VM fleet health check
    # Run as an Azure Automation runbook on a weekly schedule
    # Requires: Az.ResourceGraph, Az.Compute, Az.Monitor modules
    
    Connect-AzAccount -Identity
    
    # 1. Find stopped-but-allocated VMs
    $stoppedAllocated = Search-AzGraph -Query @"
    resources
    | where type == 'microsoft.compute/virtualmachines'
    | where properties.extended.instanceView.powerState.code == 'PowerState/stopped'
    | project name, resourceGroup, subscriptionId, location,
              vmSize = tostring(properties.hardwareProfile.vmSize)
    "@
    
    # 2. Find VMs with public IPs
    $publicIpVms = Search-AzGraph -Query @"
    resources
    | where type == 'microsoft.network/publicipaddresses'
    | where isnotempty(properties.ipConfiguration.id)
    | extend nicId = tostring(split(properties.ipConfiguration.id, '/ipConfigurations/')[0])
    | join kind=inner (
        resources
        | where type == 'microsoft.compute/virtualmachines'
        | mv-expand nic = properties.networkProfile.networkInterfaces
        | extend nicId = tostring(nic.id)
    ) on nicId
    | project vmName=name1, publicIp=properties.ipAddress
    "@
    
    # 3. Find VMs without backup
    $noBackup = Search-AzGraph -Query @"
    resources
    | where type == 'microsoft.compute/virtualmachines'
    | join kind=leftanti (
        recoveryservicesresources
        | where type =~ 'microsoft.recoveryservices/vaults/backupfabrics/protectioncontainers/protecteditems'
        | where properties.backupManagementType == 'AzureIaasVM'
        | extend vmId = tolower(tostring(properties.sourceResourceId))
    ) on \$left.id == \$right.vmId
    | project name, resourceGroup, subscriptionId, location
    "@
    
    Write-Output "=== VM Fleet Health Check ==="
    Write-Output "Stopped (allocated): $($stoppedAllocated.Count) VMs"
    Write-Output "Public IP attached:  $($publicIpVms.Count) VMs"
    Write-Output "No backup:           $($noBackup.Count) VMs"

    Common Questions About Azure Virtual Machine Optimization

    How do I find stopped-but-allocated VMs across all subscriptions?

    Use Azure Resource Graph with properties.extended.instanceView.powerState.code == 'PowerState/stopped'. This query works across all subscriptions accessible to the caller, including Lighthouse-delegated tenants. Deallocated VMs show PowerState/deallocated and do not incur compute charges.

    How much can I save by right-sizing VMs?

    Typical range: 30-50% per VM when dropping one or two size tiers. Example: D8s_v5 (8 vCPU / 32 GiB) at ~$280/month to D4s_v5 (4 vCPU / 16 GiB) at ~$140/month. Across 200 oversized VMs at 40% average savings: ~$22,400/month. Always validate against 4-6 weeks of telemetry including peak periods, batch runs, and month-end processing.

    Is it safe to downgrade Premium SSD to Standard SSD?

    For workloads with low I/O demand (less than 20% of provisioned IOPS), generally yes. Key considerations: single-instance SLA drops from 99.9% to 99.5%, boot time may increase slightly, and backup/ASR replication windows may extend. Always snapshot the disk before migrating and test in non-production first.

    What about Reserved Instances and Savings Plans?

    Right-size first, then commit. Reserving an oversized VM locks in waste for 1-3 years. After right-sizing, evaluate Reserved Instances for stable workloads (up to 72% savings) or Savings Plans for dynamic environments (up to 65% savings).

    How do I prioritize which VMs to optimize first?

    Start with the highest-cost, lowest-risk wins: (1) Deallocate stopped VMs, (2) Downgrade under-utilized Premium disks, (3) Right-size oversized VMs with consistent low utilization, (4) Migrate MMA to AMA, (5) Address security gaps.

    Should I move all VMs to Availability Zones?

    Not all VMs warrant zone-redundant deployment. Production workloads with SLA requirements: yes, target 99.99%. Dev/test environments: probably not worth the added cost and complexity. Stateful single-instance workloads: evaluate ASR as an alternative to multi-zone deployment.

    What to Do Next

    Run the fleet health check query against your Azure Resource Graph to identify stopped-allocated VMs, public IP exposure, and backup gaps across all subscriptions.
    Deallocate stopped VMs and remove unnecessary public IPs -- these are immediate wins with zero application risk.
    Review disk tier alignment for your 20 highest-cost VMs. If Premium SSD IOPS utilization is below 20%, snapshot and downgrade to Standard SSD.
    Schedule right-sizing for VMs with 30+ days of telemetry showing sustained low CPU or memory utilization, starting with non-production environments.

    Summary

    Azure VMs in "Stopped (allocated)" state incur full compute charges identical to running VMs. Deallocating eliminates 70-80% of VM cost.
    Right-sizing VMs with sustained CPU utilization below 20% typically reduces compute costs by 30-50% per VM.
    Premium SSD disks with IOPS utilization below 20% can be downgraded to Standard SSD for 40-60% savings, subject to SLA requirements.
    VMs with public IPs face automated scanning and brute-force attacks within minutes. Azure Bastion and Application Gateway provide secure alternatives.
    The MMA agent was retired August 2024. VMs still running MMA incur 20-40% higher log ingestion costs.
    Availability Zone deployment achieves 99.99% SLA versus 99.9% for single-instance VMs, but requires VM redeployment and dependency mapping.
    SQL Server VMs with data, logs, and tempdb on a single disk experience I/O contention that typically halves query throughput compared to a properly separated disk layout.

    The challenges outlined in this article — stopped-but-allocated VMs silently burning compute budget, Premium SSDs running at a fraction of provisioned IOPS, publicly exposed endpoints that should be behind Bastion — are the same ones our customers work through across their Azure environments. The difference is they use Spotto to surface these opportunities automatically, rather than running the analysis by hand.

    Stop Paying for Capacity Nobody Uses

    Spotto continuously analyzes your Azure VM fleet across all 30 optimization dimensions -- from stopped-allocated VMs and disk tier misalignment to missing backups and end-of-life operating systems -- surfacing prioritized actions with estimated cost impact and implementation risk.

    Free Trial

    Disclaimer: This article is provided for informational purposes only and does not constitute professional advice. Azure pricing, features, and service behaviour may have changed since publication. Always validate recommendations against your specific environment and consult Microsoft's official documentation before making changes to production infrastructure. Spotto is not liable for any actions taken based on the content of this article.