With Azure App Service, you can host multiple "Web Apps" in a single "App Service Plan". The App Service Plan governs how much you pay. There are multiple pricing tiers, allowing you to host your websites on more powerful VMs, but you can also scale out your App Service Plan to multiple servers.

When you scale out an App Service Plan, each Web App hosted on the plan is replicated across all the servers. For example, if you had three Web Apps, and an App Service Plan with three instances, then all three of your Web Apps would be running on each instance, and traffic would be load balanced between them:

But what if you had different scaling requirements for each web app? Maybe for one web app you only want a single instance, while another web app you'd like multiple instances? That way you could make more efficient use of the instances in your App Service Plan by only running as many instances of each website that you actually need.

Per-App Scaling

This is possible thanks to the "per-app-scaling" feature of App Service, which is available on the Standard pricing tier and above, and enables "high density hosting"

In this post I'll show you how to use Azure PowerShell to configure a simple scenario where we have three web apps (creatively named App 1, App 2 and App 3), and we want 1, 2, and 3 instances respectively on each one, with our App Service Plan scaled out to three instances. So we'd like the web apps to be arranged something like this:

Creating an App Service Plan

First, we need to create our App Service Plan and enable per-app scaling. I'm going to use the new Azure PowerShell Az module to configure this. Normally, I like to use the Azure CLI, but we're still waiting for it to support per-app scaling, so this was a good opportunity for me to try the Az module for the first time.

Just like with the Azure CLI, if we're using the PowerShell Az module for the first time, we need to log into Azure with Connect-AzAccount and make sure we're using the correct subscription with Set-AzContext

Next, we'll create a resource group for our App Service Plan with New-AzResourceGroup, and then create the App Service Plan itself with New-AzAppServicePlan, choosing the Standard pricing tier, setting up three workers, and enabling per site scaling with the -PerSiteScaling flag:

Create Web Apps

To help me test I built a very simple ASP.NET Core website with a single Razor webpage, that reads an app setting called "AppName" and also shows the machine name of the server instance that responded to the request:

I then created the following PowerShell function to create and configure a WebApp for high density hosting. It first creates the web-app with New-AzWebApp, then it publishes the application code (which I created with dotnet publish on my ASP.NET Core app and then zipped up the publish folder). Next, we use Get-AzWebApp to get details of that web app and update the SiteConfig.NumberOfWorkers to the desired number of instances for this web app. I also add a new application setting containing the site name, which my web app is going to display when the page loads. Finally, we write those settings back to the web app with Set-AzWebApp.

Limitations

So it's really nice and easy to configure per-app scaling. But there are a few limitations to be aware of.

First, the Azure Portal doesn't have any UI that lets us view or configure these settings, so you will need to script this with PowerShell or ARM templates.

Second, there is no control over scheduling of the web apps onto the individual nodes like you would have with a container orchestrator like Kubernetes, where you have concepts like "affinity" and "anti-affinity". For example, if I have four web apps: A, B, C and D, and two server instances, and I'd like A and B to be hosted together on one instance, and C and D hosted together on the other, there is no way to request that.

I also tried seeing what would happen if I asked for four workers for a particular web app on my three instance App Service Plan. It didn't error, but it seemed that only two servers were hosting my web app. Maybe it put two instances of the web app on two of the three servers, but I had no easy way of telling whether that was the case.

Summary

Per-app scaling is a welcome addition to Azure App Service that could help you make more efficient usage of an App Service Plan cluster (which could be very valuable for expensive hosting plans like ASE). But there is still a need for improved tooling and visibility, and this feature currently lacks the flexibility to control exactly how you want the web apps distributed across the server instances.

About Mark Heath

I'm a Microsoft MVP and software developer based in Southampton, England, currently working as a Software Architect for NICE Systems. I create courses for Pluralsight and am the author of several open source libraries. I currently specialize in architecting Azure based systems and audio programming. You can find me on: