Skip to main content

Azure Cost Optimization for .NET Applications: Save 40% on Your Cloud Bill

April 11, 2026 3 min read

It's entirely possible to cut an Azure bill by 30-40% without degrading performance. The changes aren't revolutionary — right-sizing, commitment discounts, intelligent autoscaling, and fixing surprisingly expensive oversights. Let's walk through the techniques that actually move the needle.

Right-Sizing: The Low-Hanging Fruit

Azure Advisor already tells you which VMs and App Service plans are over-provisioned — most teams just never look:

az advisor recommendation list \
  --category Cost \
  --query "[?shortDescription.problem=='Right-size or shutdown underutilized virtual machines'].{
    VM: resourceMetadata.resourceId,
    Savings: extendedProperties.savingsAmount,
    CurrentSKU: extendedProperties.currentSku,
    RecommendedSKU: extendedProperties.targetSku
  }" --output table

The biggest wins come from App Service plans — teams often run a single API on a P3v3 ($600/month) when a P1v3 ($120/month) handles the load. For memory-constrained plans, consider switching to workstation GC:

<PropertyGroup>
  <ServerGarbageCollection>false</ServerGarbageCollection>
</PropertyGroup>

Reserved Instances and Savings Plans

For 24/7 workloads, pay-as-you-go is leaving money on the table:

Resource Pay-as-you-go 1-Year Reserved 3-Year Reserved
D4s_v5 VM ~$280/mo ~$175/mo (37% off) ~$112/mo (60% off)
SQL Database S3 ~$150/mo ~$100/mo (33% off) ~$75/mo (50% off)

Prices approximate, vary by region. Check Azure Pricing Calculator for current rates.

Azure Savings Plans apply discounts across compute services regardless of region or size — often a better fit than reserved instances for teams that frequently resize.

Application Insights: The Hidden Cost Driver

App Insights can quietly become one of the biggest cost drivers. Fix with adaptive sampling:

builder.Services.AddApplicationInsightsTelemetry();
builder.Services.Configure<TelemetryConfiguration>(config =>
{
    var processorBuilder = config.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
    processorBuilder.UseAdaptiveSampling(maxTelemetryItemsPerSecond: 5, excludedTypes: "Event");
    processorBuilder.Build();
});

// Filter health check noise
builder.Services.AddApplicationInsightsTelemetryProcessor<HealthCheckFilter>();

Kubernetes probes hitting every pod every 10 seconds generate millions of request items monthly. Filter them out and set daily ingestion caps.

Storage Tier Optimization

Implement lifecycle management — most blob data is rarely accessed after 30 days:

{
  "rules": [{
    "name": "move-to-cool-after-30-days",
    "enabled": true,
    "type": "Lifecycle",
    "definition": {
      "filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["logs/", "exports/"] },
      "actions": {
        "baseBlob": {
          "tierToCool": { "daysAfterModificationGreaterThan": 30 },
          "tierToArchive": { "daysAfterModificationGreaterThan": 90 },
          "delete": { "daysAfterModificationGreaterThan": 365 }
        }
      }
    }
  }]
}

Hot → Cool saves ~52%; Hot → Archive saves ~91% for 1TB of storage.

Autoscaling Done Right

Scale down at night and use meaningful metrics:

az monitor autoscale create \
  --resource-group my-rg --name my-scale-settings \
  --resource "/subscriptions/{sub}/.../serverFarms/my-plan" \
  --min-count 2 --max-count 10 --count 2

az monitor autoscale rule create \
  --resource-group my-rg --autoscale-name my-scale-settings \
  --condition "CpuPercentage > 70 avg 10m" --scale out 2

az monitor autoscale rule create \
  --resource-group my-rg --autoscale-name my-scale-settings \
  --condition "CpuPercentage < 30 avg 10m" --scale in 1

For AKS, combine HPA with cluster autoscaler and KEDA for event-driven scaling based on queue depth.

Key Takeaways

  1. Right-size everything — Azure Advisor alone typically saves 15-25%.
  2. Commit to reservations — 1-year saves ~30-40%, 3-year saves ~50-60% for always-on workloads.
  3. Tame Application Insights — sampling, health check filters, and daily caps.
  4. Tier your storage — lifecycle policies for anything older than 30 days.
  5. Autoscale with intention — scale down at night, use meaningful metrics.
  6. Kill dev/test resources on schedule — shut down non-production environments outside business hours.

Start with quick wins (right-sizing, reservations, dev/test schedules), then work through Application Insights tuning, storage tiering, and autoscaling. Track progress in Azure Cost Management.

Share this post

Comments

Ajit Gangurde

Software Engineer II at Microsoft | 15+ years in .NET & Azure