Cost-Effective Azure & M365: Practical Optimization Tactics for 2026

[For IT Pros]

If you manage Azure or Microsoft 365 in 2026 and your finance team is suddenly very interested in your invoices, you’re not alone. Cloud costs creep up quietly through small decisions: a forgotten test VM here, an oversized database there, a few thousand inactive M365 accounts nobody has the heart (or process) to clean up.

This guide is the practical version of cost optimisation: specific settings, policies, queries, and scripts you can roll out this week. The goal is simple — reduce spend without breaking reliability, security, or your sanity.

1. Start with Facts: Build a Clear Cost Baseline

1.1 Use Cost Management + Tags Like an Accountant’s Chart of Accounts

Before cutting anything, make costs traceable. If you can’t answer “who owns this?” and “what is this for?” from the portal or a report, you’ll end up guessing — and guessing gets political fast.

Standardise tags across subscriptions and enforce them:

  • Required tags: CostCenter, Owner, Environment (Prod/NonProd), Application, Criticality.
  • Scope: Management groups > Policy assignment at the root so it applies to new subscriptions by default.
// Example Azure Policy: Require CostCenter and Owner on resource groups
{
  "properties": {
    "displayName": "Require CostCenter and Owner tags",
    "policyType": "Custom",
    "mode": "Indexed",
    "parameters": {},
    "policyRule": {
      "if": {
        "allOf": [
          {"field": "type", "equals": "Microsoft.Resources/subscriptions/resourceGroups"},
          {"anyOf": [
            {"field": "tags['CostCenter']", "exists": "false"},
            {"field": "tags['Owner']", "exists": "false"}
          ]}
        ]
      },
      "then": {
        "effect": "deny"
      }
    }
  }
}

Once tags are in place, use Cost Management > Cost analysis grouped by Tag: CostCenter or Tag: Environment. Export this to a storage account or Log Analytics to feed Power BI for non-technical stakeholders.

1.2 Quick Wins: Spot Obvious Waste in 30 Minutes

In the Azure Portal, check:

  • Cost Management > Cost analysis > Group by: Service – Identify top 5 services by spend (commonly Compute, Storage, SQL, Networking, Log Analytics).
  • Reservations > Recommendations – Azure will often show 20–40% savings opportunities immediately.

In M365, go to admin.microsoft.com > Billing > Licenses > Usage. This is usually where you discover you’re paying E5 for people who only read three emails a week.

2. Cut Compute Waste Without Breaking Production

2.1 Right-Size VMs with Data, Not Guesswork

Oversized VMs are still the number one Azure money drain. Use performance data to resize confidently.

With Azure Monitor / Log Analytics collecting perf metrics, run a query over the last 30 days:

Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize AvgCPU = avg(CounterValue), MaxCPU = max(CounterValue) by Computer
| where AvgCPU < 20 and MaxCPU < 60
| order by AvgCPU asc

Any VM sitting under 20% average CPU with low peaks is a resize candidate. Drop one or two sizes at a time and monitor for a week.

For batch or dev/test, use Azure Spot VMs where interruption is acceptable. They’re not for domain controllers, but they’re perfect for render farms, test agents, and one-off data processing.

2.2 Auto-Start and Auto-Stop Non-Prod

Non-production environments running 24/7 are stealth budget killers. Turn them into office-hours resources.

Use Automation + Logic Apps or the built-in Start/Stop VMs v2 solution (or just a simple script in a scheduled runbook):

# Example: Stop all Dev VMs at 19:00 UTC
Connect-AzAccount
$devVMs = Get-AzVM -Tag @{ Environment = "Dev" }
foreach ($vm in $devVMs) {
    Stop-AzVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -NoWait -Force
}

Many orgs save 30–50% on dev/test compute just by applying a weekday schedule. For global teams, define schedules per BusinessUnit or Region tag.

2.3 Use Azure Reservations and Savings Plans Intelligently

By 2026, most mature shops mix Reservations and Compute Savings Plans rather than going all-in on one model.

  • Reservations: Great for specific, stable workloads (e.g. a PostgreSQL flexible server, a fixed-size App Service plan).
  • Savings Plans: Better for overall compute spend across changing VM types and regions, especially when you refactor often.

Strategy: Cover ~60–70% of your predictable monthly compute usage with reservations/savings plans. Leave the rest pay-as-you-go for flexibility.

3. Tuning Storage, Databases, and Networking

3.1 Storage: Put Data on the Right Tier and Age It Out

Blobs and disks tend to accumulate like old fileshares. Focus on lifecycle, not just capacity.

  • Enable Azure Storage lifecycle management rules per container.
  • Use Access tiers: Hot for active data, Cool for infrequently accessed, Archive for legal/backup data you rarely touch.
// Example lifecycle rule (ARM/Bicep style) concept
{
  "name": "logs-lifecycle",
  "type": "Microsoft.Storage/storageAccounts/managementPolicies",
  "properties": {
    "policy": {
      "rules": [
        {
          "name": "MoveOldLogs",
          "enabled": true,
          "type": "Lifecycle",
          "definition": {
            "filters": {
              "blobTypes": ["blockBlob"],
              "prefixMatch": ["logs/"]
            },
            "actions": {
              "baseBlob": {
                "tierToCool": {"daysAfterModificationGreaterThan": 30},
                "tierToArchive": {"daysAfterModificationGreaterThan": 180},
                "delete": {"daysAfterModificationGreaterThan": 730}
              }
            }
          }
        }
      ]
    }
  }
}

Also review managed disk SKUs. Moving non-critical workloads from Premium SSD v2 to Standard SSD can save significantly with minimal performance impact if IOPS are low.

3.2 Databases: Stop Paying for Idle Capacity

Many Azure SQL and PostgreSQL servers are sized for peak that happens for 20 minutes a day. Shift to models that scale with load.

  • For SQL: Prefer vCore with auto-scale or serverless for bursty workloads.
  • For PostgreSQL/Flexible Server: Configure Compute auto-scale and use IO-optimised only where truly necessary.

Monitor DTU/vCore usage and connection counts. If average utilisation is < 30% with low spikes, you can usually downsize safely.

3.3 Networking: Control Egress and Premium Features

By 2026, egress and premium networking (Firewall, Private Link everywhere, Global Load Balancing) can quietly become a serious cost line.

  • Use a hub-and-spoke with a shared firewall instead of one firewall per subscription where possible.
  • Review Private Endpoints: don’t create them by default for everything; prioritise high-risk services and data.
  • Inspect egress to the internet and cross-region traffic; sometimes moving workloads into the same region as their consumers saves more than any reserved instance.

4. Microsoft 365: Licenses, Storage, and Collaboration Sprawl

4.1 Right-Size Licenses with Real Usage Data

Many organisations run with one or two license SKUs because it’s “simple.” Simplicity is expensive. Use usage-based licensing tiers.

In the M365 admin center, review:

  • Reports > Usage > Apps usage – Who actually uses Teams, Office desktop apps, SharePoint, OneDrive?
  • Security & Compliance features – Are you paying for E5 security for accounts that never log in externally?

Pattern that works well in 2026:

  • E5 or E5 Security add-on for high-risk roles (C-level, IT admins, finance, privileged users).
  • E3 + add-ons or Business Premium for standard knowledge workers.
  • F3/Frontline for shop-floor, warehouse, or kiosk workers.

4.2 Remove Licenses from Inactive Accounts Automatically

Orphaned licenses pile up when HR, IT, and identity don’t talk well. Automate cleanup based on Entra ID and usage.

Example PowerShell (run via Azure Automation or GitHub Actions):

Connect-MgGraph -Scopes User.Read.All, Directory.Read.All

# Find users inactive for 90 days based on sign-in logs (Entra sign-in logs export required)
$inactiveUsers = Get-MgUser -Filter "accountEnabled eq true" -All | Where-Object {
    # Pseudo: check custom attribute or external log to get last sign-in
    $_.ExtensionProperty["LastSignInDays"] -gt 90
}

foreach ($user in $inactiveUsers) {
    $licenses = (Get-MgUserLicenseDetail -UserId $user.Id)
    if ($licenses) {
        Write-Output "Removing licenses from $($user.UserPrincipalName)"
        Set-MgUserLicense -UserId $user.Id -RemoveLicenses $licenses.SkuId -AddLicenses @{}
    }
}

Integrate this with your joiner/mover/leaver process: when HR flags a leaver in your HR system, your identity workflow should disable the account and reclaim licenses within 24 hours.

4.3 Control OneDrive and SharePoint Storage Growth

Unlimited-sounding storage feels free to users, but it isn’t free to you. Put guardrails in place:

  • Set reasonable OneDrive quotas (e.g. 250–500 GB by default; higher on request with justification).
  • Use SharePoint site lifecycle policies – auto-archive or lock sites after projects close.
  • Enable storage alerts for heavy-hitter sites to catch “someone uploaded 4 TB of CCTV footage” early.

5. Governance: Make Cost Awareness Part of the Platform

5.1 Enforce Guardrails with Policy and Blueprints

You don’t want to manually police every developer or project. Let Azure Policy do the policing for you.

  • Deny ultra-expensive SKUs in non-prod (e.g. M-series or H-series VMs).
  • Require budgets on every subscription with email and webhook alerts.
  • Audit public IPs, premium services, and zone-redundant options to ensure they are intentional.
// Example: Deny M-series in non-production
{
  "properties": {
    "displayName": "Deny M-series in non-production",
    "mode": "Indexed",
    "parameters": {},
    "policyRule": {
      "if": {
        "allOf": [
          {"field": "type", "equals": "Microsoft.Compute/virtualMachines"},
          {"field": "tags['Environment']", "notEquals": "Prod"},
          {"field": "Microsoft.Compute/virtualMachines/sku.name", "like": "Standard_M*"}
        ]
      },
      "then": {"effect": "deny"}
    }
  }
}

Bundle these into a platform landing zone so every new subscription starts with sensible defaults instead of expensive chaos.

5.2 Give Product Teams Cost Dashboards They Can Understand

People only optimise what they can see. Build simple cost dashboards per application or product area.

  • Use tags (Application, Product) to group resources.
  • Export cost data to a Log Analytics workspace or Azure Data Explorer.
  • Build Power BI dashboards showing monthly cost, forecast, and top resources per app/team.

Then make this part of regular rituals: include cost as a line item in sprint reviews or monthly service reviews. When a team can see their own spend trend, they often volunteer optimisation ideas.

5.3 Put Budgets and Alerts Close to the Spend

Azure Budgets are often set once and forgotten. Use them actively:

  • Create budgets per subscription and per key CostCenter.
  • Set thresholds at 50%, 80%, 100% and hook them to email, Teams, and optionally a Logic App that can trigger an escalation or even pause non-critical resources.
# Example: Create a budget via Azure CLI
az consumption budget create \
  --amount 5000 \
  --category cost \
  --name AppX-Prod-Budget \
  --time-grain monthly \
  --resource-group RG-AppX-Prod \
  --start-date 2026-01-01 \
  --end-date 2026-12-31 \
  --notification key=Actual_80 \
      threshold=80 \
      operator=GreaterThan \
      [email protected]

6. A 30-Day Cost Optimisation Action Plan

To keep this practical, here’s a simple 30-day plan you can run in parallel with your day job.

Week 1: Visibility & Tagging

  • Define tag standards and enforce them with Azure Policy.
  • Group cost analysis by CostCenter and Environment to identify the top 3 spenders.
  • Review M365 license usage and list obvious down-tier candidates.

Week 2: Compute & Storage

  • Run performance queries on VMs and databases; right-size 10–20 low-risk workloads.
  • Implement auto-shutdown schedules for dev/test VMs.
  • Configure lifecycle rules for at least one large storage account (logs/backups).

Week 3: Licenses & Automation

  • Automate license removal for inactive M365 users.
  • Adjust license tiers for at least one department based on actual usage.
  • Set up a recurring cost export and a simple Power BI dashboard.

Week 4: Governance & Guardrails

  • Deploy policies to deny high-cost SKUs in non-prod.
  • Create budgets and alerts on your top 3 subscriptions.
  • Agree with product owners how cost will be reviewed each month.

One Concrete Next Step

Today, pick one subscription and a single M365 tenant, and run a quick cost review: top 5 services in Azure, and the top 3 license SKUs in M365 by spend. Turn those lists into a short action sheet (resize X, schedule shutdown for Y, down-tier licensing for Z). Don’t aim for perfection — just ship the first few changes and let the savings fund the time you’ll spend doing deeper optimisation.