Azure Cost Optimization for .NET Applications: Save 40% on Your Cloud Bill
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
- Right-size everything — Azure Advisor alone typically saves 15-25%.
- Commit to reservations — 1-year saves ~30-40%, 3-year saves ~50-60% for always-on workloads.
- Tame Application Insights — sampling, health check filters, and daily caps.
- Tier your storage — lifecycle policies for anything older than 30 days.
- Autoscale with intention — scale down at night, use meaningful metrics.
- 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.
Comments
Ajit Gangurde
Software Engineer II at Microsoft | 15+ years in .NET & Azure