Skip to content

Azure App Service Pricing Tiers Explained: Which One for Your .NET App?

Free, Basic, Standard, Premium v3/v4 or Isolated? What each Azure App Service tier gives you, the billing rules that catch people out, the .NET details that matter (Always On, background services, Linux vs Windows), and how to pick the right tier for your ASP.NET Core app.

Isaiah Clifford Opoku
Isaiah Clifford OpokuSoftware Engineer & ArchitectNovember 4, 2026·18 min read

You’ve built an ASP.NET Core app, you open the Azure portal to deploy it, and you’re asked to pick a pricing tier: F1, D1, B1, S1, P0v3, P1v4, P1mv4, I1v2… and a price that ranges from free to “please talk to finance”. Most people pick something at random, or pick whatever the tutorial used, and find out later that it either can’t do what they need or costs three times what it should.

This post explains what each App Service tier actually gives you, the billing rules that catch people out, the .NET-specific details that matter (Always On, background services, 32-bit vs 64-bit, Linux vs Windows), and finally a simple way to choose the right tier for your app.

A note on prices: Azure prices vary by region, operating system, and currency, and they change. The figures in this post are rough, indicative pay-as-you-go ballparks to help you compare tiers. Always check the App Service pricing page and the pricing calculator for your region before committing.

First: what you’re actually paying for

Before comparing tiers, you need one concept clear, because it explains almost every billing surprise: you don’t pay for apps. You pay for an App Service plan.

An App Service plan is a set of virtual machines in one region. A web app is something that runs on a plan. Microsoft’s docs put it like this: when you create a plan, “you create a set of compute resources for that plan in that region. Whatever apps you put into the App Service plan run on those compute resources.” (Microsoft Learn — App Service plans)

That has some important consequences:

  1. On dedicated tiers (Basic and up), you’re billed per VM instance, per hour, no matter how many apps run on it. One app or ten apps on a single B1 instance costs the same.
  2. Stopping an app doesn’t stop the bill. The plan’s VMs are still allocated to you. To stop paying, you have to delete the plan or scale it down to Free.
  3. Apps on the same plan share the same CPU and memory. A memory leak in one app slows down every other app on that plan.
  4. Deployment slots aren’t free compute. A staging slot runs on the same VMs as production. It doesn’t cost extra money, but it does use the plan’s CPU and memory.
  5. Scaling out multiplies the cost. Three instances of P1v3 cost three times one instance.

So “which tier?” really means two questions: what size and type of VM (the tier and SKU), and how many of them (the instance count).

The three categories

All tiers fall into three groups:

Category Tiers What it means
Shared compute Free (F1), Shared (D1) Your app runs on a VM shared with other customers’ apps, with a daily CPU quota. For learning and experiments only.
Dedicated compute Basic, Standard, Premium v2, Premium v3, Premium v4 You get VMs no other customer uses. Apps in your plan share them with each other. This is where real apps live.
Isolated Isolated v2 (App Service Environment v3) Dedicated VMs inside your own virtual network, fully single-tenant. For strict compliance and very large scale.

Now let’s go through each tier, from cheapest to most expensive.

Free (F1): for learning, not for anything real

CPU Shared, 60 CPU minutes per day
Memory 1 GB
Storage 1 GB
Scale out No (1 shared instance)
Custom domain No, only yourapp.azurewebsites.net
SLA None
Price Free

F1 is great for one thing: deploying your first ASP.NET Core app to see how App Service works. Beyond that, it has hard limits you’ll hit quickly:

  • 60 CPU minutes per day (and 3 minutes per 5-minute window). Once you use them up, your app stops responding with a quota error until the quota resets.
  • No Always On. The app is unloaded after a period of no traffic, so the next visitor waits for a cold start while .NET spins back up.
  • No custom domain, no SLA, and Microsoft explicitly says it’s not supported for production.

Shared (D1): rarely the right choice

CPU Shared, 240 CPU minutes per day
Memory 1 GB
Custom domain Yes, but no SSL for it
Scale out No
SLA None
OS Windows only
Price Low, charged per app

D1 gives you four times F1’s CPU quota and lets you add a custom domain. But you can’t bind an SSL certificate to that custom domain, so https://www.yourapp.com won’t work properly. In 2026, a site without HTTPS isn’t really usable. Combine that with no Always On and no SLA, and Basic is almost always a better use of money.

Basic (B1, B2, B3): the cheapest tier for a real app

B1 B2 B3
vCPU 1 2 4
Memory 1.75 GB 3.5 GB 7 GB
Storage 10 GB 10 GB 10 GB

What you get:

  • Dedicated VMs, so no CPU quota.
  • Always On, so your app stays loaded and there’s no cold start.
  • Custom domains with SSL, including the free App Service Managed Certificate.
  • Manual scale out to 3 instances.
  • VNet integration and private endpoints, so the app can reach a database inside a virtual network.
  • 99.95% SLA.
  • Backups every 2 hours, up to 12 per day.

What you don’t get:

  • No autoscale. You set the instance count yourself.
  • No deployment slots, so no zero-downtime “deploy to staging, then swap”.
  • No savings plans or reserved instances.

Rough price: a B1 on Linux is around the cost of a takeaway lunch per month (roughly $13–15). The same B1 on Windows costs several times more (roughly $55). That Linux vs Windows gap is one of the biggest savings available, and we’ll come back to it.

Who it’s for: side projects, internal tools, small business sites, low-traffic APIs, dev and test environments. A small ASP.NET Core API runs comfortably on B1. Keep an eye on memory though: 1.75 GB fills up faster than you’d think with EF Core, caching, and a few background services.

Standard (S1, S2, S3): the classic production tier

S1 S2 S3
vCPU 1 2 4
Memory 1.75 GB 3.5 GB 7 GB
Storage 50 GB 50 GB 50 GB

What it adds over Basic:

  • Autoscale, adding and removing instances based on CPU, memory, or a schedule.
  • Scale out to 10 instances.
  • 5 deployment slots per app, so you can deploy to staging, warm it up, and swap with zero downtime.
  • One IP-based SSL connection included.

Rough price: around $70 a month per instance (similar on Windows and Linux).

For years, Standard was the answer to “what tier for production?”, and a lot of tutorials still say so. But look at the specs: the same 1.75 GB of memory as B1, on older hardware. That brings us to the most useful piece of advice in this post.

Premium v3 (P0v3–P5mv3): usually better value than Standard

SKU vCPU Memory
P0v3 1 4 GB
P1v3 2 8 GB
P2v3 4 16 GB
P3v3 8 32 GB
P1mv3 → P5mv3 2 → 32 16 GB → 256 GB (memory-optimized)

What it adds over Standard:

  • Newer, faster hardware.
  • More memory per vCPU: P0v3 has 4 GB, more than twice S1’s 1.75 GB.
  • Scale out to 30 instances, and 20 deployment slots.
  • 250 GB storage and hourly backups (up to 50 per day).
  • Zone redundancy, spreading instances across availability zones in the region.
  • Automatic scaling, a simpler, HTTP-traffic-based alternative to writing autoscale rules, with pre-warmed instances.
  • Savings plans and reserved instances, which can bring the price down significantly if you commit to one or three years.
  • Memory-optimized “m” SKUs for apps that need lots of RAM but not lots of CPU.

The key insight: P0v3 often costs about the same as S1 (especially on Linux, and especially with a savings plan), while giving you more than twice the memory, faster hardware, 4x the slots, 3x the max instances, and zone redundancy. If you’re about to pick S1 for a new app, price out P0v3 first. For most new production apps, Standard is no longer the best choice.

Rough price: P0v3 on Linux is in the same range as S1. P1v3 is roughly double that. Windows costs more at every size.

Premium v4 (P0v4–P5mv4): the newest generation

Premium v4 became generally available in September 2025 on both Windows and Linux. The sizes mirror Premium v3:

SKU vCPU Memory
P0v4 1 4 GB
P1v4 2 8 GB
P2v4 4 16 GB
P3v4 8 32 GB
P1mv4 → P5mv4 2 → 32 16 GB → 256 GB (memory-optimized)

The difference is the hardware underneath. Microsoft claims at least 25% better price-performance than Premium v3, and lower pay-as-you-go prices on Windows in particular. It also adds built-in network isolation features.

Premium v4 is also the only tier that supports Managed Instance on App Service, a newer option for Windows apps that need OS-level customization: PowerShell setup scripts, registry settings, storage mounts, RDP access for diagnostics, and support for legacy Windows dependencies. It’s aimed squarely at old .NET Framework apps that you want to move to App Service without rewriting them first. (At the time of writing it’s Windows-only, Pv4/Pmv4 only, and available in select regions.)

Should you use v4 or v3? For a new app, if Premium v4 is available in your region, compare the two in the pricing calculator. With better hardware and a claimed better price-performance, v4 will often win. Premium v3 is still a solid, widely available choice, and existing v3 plans don’t need to move urgently.

Watch out for old Premium plans. If you have older plans on Premium v1 (P1, P2, P3) or Premium v2, you’re paying for older hardware. Moving to v3 or v4 usually gets you better performance for the same or less money.

Isolated v2 (I1v2–I6v2): for compliance and very large scale

Runs on An App Service Environment v3 (ASE) inside your own VNet
vCPU / memory 2 → 64 vCPU, 8 GB → 256 GB
Storage 1 TB
Scale out 100 instances per plan (more on request)

Isolated v2 is a different kind of product. You deploy an App Service Environment into a subnet of your own virtual network. Your apps run on VMs that are single-tenant (no other customer’s apps on the same hardware), and the whole environment can be completely private, with no public internet endpoint at all.

Who it’s for: banks, healthcare, government, and other organizations with regulatory requirements for network and compute isolation, and very large deployments that need hundreds of instances.

Who it’s not for: almost everyone else. It’s by far the most expensive option. And with VNet integration and private endpoints now available from Basic upwards, plus Premium v4’s network isolation features, many apps that once needed an ASE no longer do. (The older ASE v1 and v2 were retired in 2024. If you’re still on them, you need to migrate to ASE v3.)

The full comparison

Feature Free Shared Basic Standard Premium v3/v4 Isolated v2
Compute Shared, 60 min/day Shared, 240 min/day Dedicated Dedicated Dedicated Dedicated, single-tenant
Max instances 1 1 3 10 30 100+
Autoscale ✗ ✗ ✗ ✓ ✓ (+ automatic scaling) ✓
Always On ✗ ✗ ✓ ✓ ✓ ✓
Custom domain ✗ ✓ ✓ ✓ ✓ ✓
SSL on custom domain ✗ ✗ ✓ ✓ ✓ ✓
Deployment slots ✗ ✗ ✗ 5 20 20
Backups ✗ ✗ Every 2h, 12/day Every 2h, 12/day Hourly, 50/day Hourly, 50/day
VNet integration ✗ ✗ ✓ ✓ ✓ Native (inside your VNet)
Private endpoints ✗ ✗ ✓ ✓ ✓ Built-in isolation
Zone redundancy ✗ ✗ ✗ ✗ ✓ ✓
Storage 1 GB 1 GB 10 GB 50 GB 250 GB 1 TB
SLA None None 99.95% 99.95% 99.95% 99.95%
Savings plans / reservations ✗ ✗ ✗ ✗ ✓ ✓

Source: Microsoft Learn — App Service limits. Limits change, so check the current table.

.NET-specific things that affect your choice

Generic pricing guides skip these, but they matter a lot for ASP.NET Core apps.

1. Background services need Always On

If your app uses BackgroundService, IHostedService, Hangfire, Quartz.NET, or WebJobs, this one is critical. Without Always On, App Service unloads your app after a period with no HTTP traffic. When the app unloads, your background services stop with it. Your “send reminder emails every 10 minutes” job quietly stops running at 2am because nobody visited the site.

// This only keeps running while the app is loaded.
// On Free/Shared (no Always On), it stops whenever the app goes idle.
public class ReminderEmailService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        using var timer = new PeriodicTimer(TimeSpan.FromMinutes(10));
        while (await timer.WaitForNextTickAsync(stoppingToken))
        {
            // send reminders...
        }
    }
}

Always On is available from Basic upwards and is off by default, so turn it on:

az webapp config set --name my-app --resource-group rg-myapp --always-on true

Also remember that with multiple instances, every instance runs your background services. Scale to three instances and your reminder job runs three times. Use a distributed lock, a job library with clustering support, or move the work to Azure Functions or a separate worker.

2. Linux vs Windows: Linux is usually cheaper

Modern .NET (.NET 8, 9, 10) runs perfectly on Linux, and Linux plans are noticeably cheaper, especially on Basic, where Windows can cost around four times as much. Unless you need Windows, choose Linux.

You do need Windows if your app:

  • targets .NET Framework (4.x), or
  • depends on Windows-only things: System.Drawing on Windows, COM components, the Windows registry, IIS modules, or Windows authentication.

3. 32-bit vs 64-bit and memory

Free and Shared on Windows only run 32-bit processes, which caps how much memory your app can use. On Basic and up you can switch to 64-bit (Linux is always 64-bit). If you see OutOfMemoryException on a Windows plan that seems to have plenty of RAM, check this setting first.

Also remember that the memory listed for a SKU is for the whole VM, shared by every app and slot on the plan. A B1’s 1.75 GB with three apps and a staging slot is not 1.75 GB per app.

4. Slots for zero-downtime deployment

The “deploy to staging slot, warm up, swap” workflow is the standard way to ship ASP.NET Core apps without downtime. It needs Standard or above. If you’re on Basic, each deployment restarts the app, so users see errors or a slow first request. If that matters to you, it’s a good reason to move up a tier, and another reason to compare P0v3 with S1.

5. Health checks need more than one instance

App Service’s Health check feature (point it at an endpoint like /healthz from builder.Services.AddHealthChecks()) takes unhealthy instances out of the load balancer and replaces them. That only helps if there’s another instance to send traffic to. On a single instance, there’s nowhere else to route.

How to choose: a practical guide

Your situation Recommended tier
Learning, a demo, “hello world” Free (F1)
Side project, portfolio, internal tool, dev/test environment Basic B1 on Linux
Small production app, low traffic, downtime during deploys is OK Basic B1/B2
Production app that needs zero-downtime deploys or autoscale Premium v3 or v4 (P0v3/P0v4). Compare with S1, but Premium usually wins.
Growing SaaS, needs high availability Premium v3/v4, 2+ instances, zone redundancy
Memory-heavy app (large caches, in-memory processing) Premium memory-optimized (P1mv3/P1mv4 and up)
Legacy .NET Framework app with Windows dependencies Windows Premium v4, and look at Managed Instance
Regulatory requirement for full network and compute isolation Isolated v2 (App Service Environment v3)
Background jobs must run reliably Anything Basic or above, with Always On enabled

Start small and scale up. You can change tier at any time, with no redeploy:

az appservice plan update --name plan-myapp --resource-group rg-myapp --sku P0V3

Creating a plan: CLI and Bicep

With the Azure CLI, a Linux Premium v3 plan and a .NET web app:

az group create --name rg-myapp --location eastus

az appservice plan create \
  --name plan-myapp \
  --resource-group rg-myapp \
  --sku P0V3 \
  --is-linux

az webapp create \
  --name my-dotnet-app \
  --resource-group rg-myapp \
  --plan plan-myapp \
  --runtime "DOTNETCORE:10.0"

The same thing in Bicep, so it’s repeatable and lives in source control:

param location string = resourceGroup().location

resource plan 'Microsoft.Web/serverfarms@2023-12-01' = {
  name: 'plan-myapp'
  location: location
  kind: 'linux'
  sku: {
    name: 'P0v3'
    capacity: 1
  }
  properties: {
    reserved: true // required for Linux plans
  }
}

resource app 'Microsoft.Web/sites@2023-12-01' = {
  name: 'my-dotnet-app'
  location: location
  properties: {
    serverFarmId: plan.id
    httpsOnly: true
    siteConfig: {
      linuxFxVersion: 'DOTNETCORE|10.0'
      alwaysOn: true
      healthCheckPath: '/healthz'
    }
  }
}

Ways to cut your App Service bill

  1. Use Linux unless you need Windows. It’s the single biggest saving, especially on Basic.
  2. Put several small apps on one plan. You pay per VM, not per app. A small API, an admin site, and a webhook receiver can share one B1 or P0v3. Just watch memory, and split apps out when one starts affecting the others.
  3. Compare P0v3/P0v4 with S1 before choosing Standard.
  4. Use a savings plan or reserved instances for production plans you know will run for a year or more (Premium v3 and up).
  5. Use Dev/Test pricing for non-production subscriptions if you have a Visual Studio subscription or an Enterprise Dev/Test offer.
  6. Scale down outside working hours. Use scheduled autoscale rules for dev/test plans, or scale a non-production plan down to fewer instances overnight.
  7. Delete plans you’re not using. A stopped app on a running plan still costs money. Empty plans also cost money. Check for leftovers.
  8. Set a budget alert in Microsoft Cost Management so a forgotten P3v3 doesn’t surprise you at the end of the month.

When App Service isn’t the right fit

App Service is a great default for ASP.NET Core web apps and APIs, but a few cases are better served elsewhere:

  • Traffic is very spiky or often zero. App Service always charges for at least one instance. Azure Container Apps can scale to zero, so you pay nothing when idle.
  • Event-driven or scheduled jobs. Azure Functions (Flex Consumption plan) charges per execution and is a natural home for “run every 10 minutes” or “process this queue” work.
  • Blazor WebAssembly or a static front end. Azure Static Web Apps hosts static sites cheaply, or for free, with a global CDN.
  • Microservices with lots of containers. Container Apps or AKS give you more control over networking and scaling between services.

Conclusion

The App Service tier list looks intimidating, but it boils down to a few decisions.

Free and Shared are for learning only: daily CPU quotas, no Always On, no SLA. Basic is the cheapest tier for a real app, and B1 on Linux is a great home for side projects, internal tools, and small APIs, as long as you’re fine without autoscale and deployment slots. Standard used to be the default production answer, but for a new app Premium v3 or v4 usually gives you much more (more memory, newer hardware, 20 slots, zone redundancy, savings plans) for a similar price, so always compare P0v3/P0v4 with S1. Isolated v2 is for strict isolation requirements and very large scale.

On top of that, remember the rules that cause most surprises: you pay per plan instance, not per app; stopped apps still cost money; slots share the plan’s resources; and for .NET specifically, background services need Always On, and Linux saves real money unless you’re tied to Windows.

Pick the smallest tier that has the features you need today. You can always scale up later with one command.

Further reading

Found this useful? Share it

XLinkedIn

Discussion