🚀 Executive Summary

TL;DR: Azure’s ‘Always On’ feature can lead to unexpected costs by reserving idle resources across App Service, ACA, and VMs. Understanding each service’s specific billing model and optimizing resource allocation, such as consolidating App Service Plans or setting `min-replicas` in ACA, is crucial to avoid surprise bills.

🎯 Key Takeaways

  • Azure’s ‘Always On’ feature implies a financial commitment to reserved resources (CPU, memory, networking), meaning you pay for a ‘ready’ state, not just active execution.
  • For App Service, cost optimization hinges on the App Service Plan, which is the billing unit; consolidating multiple low-traffic apps onto a single, appropriately sized plan is crucial.
  • Azure Container Apps (ACA) achieve ‘always on’ by setting `min-replicas=1`, incurring a reduced ‘idle’ rate for provisioned resources, often more cost-effective than dedicated App Service Plans for modern apps.

Azure costs for ‘always on’ services can be deceptive. I’m breaking down the real-world cost and performance of Azure Container Apps (ACA), App Service, and VMs to help you avoid that dreaded surprise bill from an idle-but-expensive resource.

The Azure ‘Always On’ Cost Trap: My Real-World Take on ACA vs. App Service vs. VMs

I remember this one sprint, maybe two years back. We had a junior dev, sharp kid, who was tasked with deploying a new internal tool. It was a simple API, didn’t get much traffic, but it needed to be available 24/7 for the overnight data sync jobs. He put it on an App Service, flipped the “Always On” switch, and moved on. Seemed logical. A month later, our Azure cost alerts started screaming. The bill for that “simple” internal tool was higher than some of our production services. He’d picked a beefy S2 App Service Plan, thinking “Always On” was just a magic toggle. He learned a hard lesson that day: in the cloud, “Always On” isn’t a feature, it’s a financial commitment, and the devil is in the details of how you commit.

The “Why”: You’re Not Paying for “On”, You’re Paying for “Ready”

This whole problem boils down to a simple misunderstanding of what you’re renting from Microsoft. When you ask for an “always on” service, you’re not just flipping a switch. You are reserving a slice of a physical server in a data center somewhere. Whether your code is executing or just sitting there waiting for a request, that slice of silicon, memory, and networking is allocated to you. And you’re paying for it.

  • App Service Plans: You pay for the underlying VM (the Plan), not the individual app. “Always On” just keeps your app’s worker process loaded into memory so it doesn’t have a cold start. The plan itself is always running and always costing you money.
  • Virtual Machines: This is the most straightforward. The VM is running? You’re paying. It’s off? You’re not (mostly, you still pay for storage). It’s simple and honest.
  • Azure Container Apps (ACA): This is the tricky one. It feels “serverless,” but to be “always on,” you have to set minimum replicas to 1. This means you’re paying for idle resources, though at a lower rate than active ones. It’s a hybrid model that can bite you if you’re not watching the fine print.

Let’s walk through the common scenarios and how I’d approach them in the real world, not the documentation-perfect world.

Solution 1: The Pragmatic App Service Tune-Up

This is for the teams who are already invested in App Services and don’t want to re-architect everything. The goal isn’t to eliminate the cost, but to make it sane. That junior dev’s mistake wasn’t using “Always On”; it was using an oversized, underutilized App Service Plan.

The Fix: Stop thinking about the app and start thinking about the Plan. The App Service Plan is the billing unit. Can that “always on” internal tool run on a B1 (Basic) or S1 (Standard) plan instead of an S2? Better yet, can you consolidate multiple low-traffic “always on” apps onto a single, reasonably sized plan? If you have `prod-api-01`, `prod-background-worker-02`, and `dev-test-utility-app` all on their own S1 plans, you’re just burning money. Consolidate them onto one plan if their resource needs are compatible.

Pro Tip: Don’t use “Always On” for your staging or dev environments unless you have a specific need for it (like integration testing). Use deployment slots for testing and spin them down, or just accept the cold start. Your budget will thank you.

Solution 2: The Modern Approach with Azure Container Apps

For new projects or when you’re ready to modernize, I almost always lean towards ACA now. It gives you the best of both worlds: serverless scaling and the ability to have a warm instance ready to go. But you have to be deliberate about it.

The Fix: To make an ACA “always on,” you set its minimum replicas to 1. This guarantees you always have one container instance running. You’ll pay a reduced “idle” rate for the CPU and memory this replica consumes when it’s not actively processing requests. This is almost always cheaper than a dedicated App Service Plan of equivalent power.

Here’s how you’d set that with the Azure CLI. Notice the `min-replicas` setting.


az containerapp update \
  --name my-always-on-app \
  --resource-group my-resource-group \
  --min-replicas 1 \
  --max-replicas 3

This approach gives you a warm instance ready for traffic, but it can still scale out to handle bursts. It’s the sweet spot for most modern, containerized web APIs and background services.

Solution 3: The ‘Old School’ and Predictable VM

Don’t let the “serverless-first” crowd fool you. Sometimes, a plain old Virtual Machine is the smartest and most cost-effective choice. I call this the “no magic” option. There’s no complex billing for idle vs. active, no plans, no replicas—just a server that’s on or off.

The Fix: If you have a legacy application that isn’t easily containerized, or a service with very steady, predictable resource usage (like a custom build agent or a scheduled task runner), just put it on a VM. A B-series (burstable) VM can be incredibly cheap if the load is low. You know exactly what you’re paying for each month. For `legacy-reporting-vm` that runs a big job once a night but needs to be “on” to listen, a B2s instance with a 3-year reserved instance discount can be dirt cheap and entirely predictable.

It feels archaic, but financial predictability is a feature, not a bug.

The Final Tally: A Quick Comparison

Service Best For… Cost Model Gotcha
App Service Existing PaaS apps, monoliths, teams comfortable with the model. Pay for the Plan (the underlying VM) 24/7. Forgetting to consolidate apps onto a single plan is a huge money-waster.
Container Apps Modern containerized apps, microservices, APIs needing to scale. Pay-per-second for active use, plus a lower rate for idle provisioned resources (`minReplicas >= 1`). The “idle” charge can surprise you if you set minReplicas > 0 and forget about it.
Virtual Machine Legacy apps, long-running tasks, maximum control, predictable costs. Pay for the VM uptime by the hour/second. Very predictable. You are responsible for EVERYTHING: OS patching, security, monitoring, etc.

Ultimately, there’s no single right answer. But by understanding what you’re actually paying for, you can stop making accidental donations to the cloud provider’s bottom line and start making intentional, cost-effective architectural choices. Don’t be the dev with the surprise bill.

Darian Vance - Lead Cloud Architect

Darian Vance

Lead Cloud Architect & DevOps Strategist

With over 12 years in system architecture and automation, Darian specializes in simplifying complex cloud infrastructures. An advocate for open-source solutions, he founded TechResolve to provide engineers with actionable, battle-tested troubleshooting guides and robust software alternatives.


🤖 Frequently Asked Questions

âť“ What is the ‘Always On’ cost trap in Azure?

The ‘Always On’ cost trap arises from misunderstanding that you pay for reserved resources (CPU, memory, networking) even when idle, not just active execution, across services like App Service, ACA, and VMs.

âť“ How do Azure Container Apps, App Service, and VMs compare for ‘always on’ services?

App Service charges for the underlying Plan 24/7; ACA charges for active use plus a lower idle rate for `min-replicas >= 1`; VMs charge for uptime, offering predictable costs but requiring full management.

âť“ What is a common implementation pitfall for ‘always on’ App Services and how can it be avoided?

A common pitfall is using an oversized, underutilized App Service Plan or failing to consolidate multiple low-traffic ‘always on’ apps onto a single, cost-effective plan like B1 or S1.

Leave a Reply

Discover more from TechResolve - SaaS Troubleshooting & Software Alternatives

Subscribe now to keep reading and get access to the full archive.

Continue reading