App Service: the plan drives the bill
A Web App runs in an App Service plan, which reserves instances. You pay for these instances continuously, whether the applications are busy or not. The levers:
- Choose the right tier. Premium and Isolated are justified for performance, isolation or security. Outside prod, Basic or Standard is almost always enough.
- Size on real usage. We look at CPU and memory over several weeks. Real example: a plan that never exceeded 50% of its capacity for three weeks, moved from B3 to B1, saw its daily cost drop by two thirds.
- Linux by default. On every tier, a Windows plan costs more than a Linux plan, and Azure Hybrid Benefit doesn't apply.
- Delete empty plans. Deleting all the apps in a plan doesn't delete the plan, which is still billed.
- Share the Web Apps and Functions of the same scope on an existing plan.
- Autoscaling in prod if the load follows a day-night or seasonal cycle, and a single minimum instance outside prod.
- Reserve stable Premium v3 plans, once usage is optimized.
An Azure Resource Graph query is enough to find empty plans:
Resources
| where type =~ 'microsoft.web/serverfarms'
| where properties.numberOfSites == 0
| project name, resourceGroup, sku = tostring(sku.name)
Before downsizing a plan for an application that relies heavily on multithreading, we test the impact on performance: fewer cores can slow some workloads down.
Azure Functions
On the Consumption plan, you pay per execution: nothing to size. In an App Service plan, capacity is fixed, whatever the activity. For continuous activity, the dedicated plan can be cheaper; for occasional activity, it is the opposite. The hosting plan is chosen at creation: changing it means redeploying.
Azure SQL Database
- Rightsizing of vCores or DTUs based on real usage.
- Serverless with auto-pause for lightly used databases, typically outside prod.
- Elastic pools when several databases peak at different times.
- Reservation of vCores for stable production databases.
- Challenged geo-replication: it roughly doubles the cost, and is not always justified outside prod.
MySQL, PostgreSQL and MariaDB
MySQL and PostgreSQL flexible servers can be stopped: they restart automatically after 30 days, so stopping must be automated. In non-prod, it is the same reasoning as VM Stop/Start. In prod: rightsizing, reservation and justified geo-replication.
Cosmos DB
Autoscale throughput rather than throughput provisioned for the peak, serverless mode for low traffic, reserved capacity for stable prod, and geo-redundancy limited to the regions you really need.
Application Gateway, Front Door and Event Hubs
- Application Gateway: a fixed hourly cost plus capacity units. Autoscaling with a low minimum instance count, WAF only where it is useful, and gateways shared across applications.
- Front Door: when an origin group has a single backend, health probes are useless and can be disabled.
- Event Hubs: auto-inflate increases throughput units but doesn't scale them back down on its own. Set a maximum and return to the real need.