Azure App Service Deep Dive: Architecture, Scaling, Networking and Operations
A book-style walkthrough of how Azure App Service really works under the hood, from plans and front ends to private networking, deployment slots, isolated environments and production-grade operations.
Imagine you want to open a restaurant. You could buy land, pour a foundation, wire the electricity, hire plumbers and install a gas line before you ever cook a single meal. Or you could rent a fully equipped kitchen inside a busy food hall, where the building, power, water, security guards and cleaning crew are already taken care of, and all you bring is your recipes and your chefs. Azure App Service is that equipped kitchen for web applications. You bring the code, and Microsoft runs the building.
This guide goes far beyond the first-day basics. We will open the walls of the food hall and look at the pipes: how requests find your app, how plans share machines, why some scaling settings fight each other, how private networking really works, when a fully isolated environment makes sense, and which mistakes quietly hurt production systems. Every new word is explained when it first appears, and every big idea comes with a real-life comparison so the picture stays in your head.
1What Azure App Service Really Is
App Service is a managed platform for running web apps, APIs and background jobs without looking after servers.
The Simple Definition
Azure App Service is a Platform as a Service product, usually shortened to PaaS. PaaS means the cloud provider manages the machines, the operating system, the patching, the web server and the load balancing, while you manage only your application and its settings. It exists because most teams do not want to spend their weekends installing security updates on servers. It is used for websites, REST APIs, mobile backends and light background workers.
An App Service app can run as plain code in a supported language stack, such as .NET, Java, Node.js, Python or PHP, or it can run as a container image that you build yourself. In both cases the platform provides a public address, TLS certificates, scaling, logging and deployment tools out of the box.
Think of three ways to get a pizza. Making it at home means you buy flour, own the oven and clean the kitchen. That is like virtual machines. Ordering from a pizza shop means you pick toppings and somebody else handles everything else. That is like App Service. Buying a frozen slice from the supermarket means you just heat and eat, which is closer to a pure serverless function.
What You Manage and What Microsoft Manages
The line of responsibility is the most important idea to understand early. Microsoft owns the physical datacenter, the host machines, the hypervisor, the operating system images, the patching schedule, the runtime updates for built-in stacks and the platform load balancers. You own your application code, its configuration, its identity and access choices, its data, its network design choices and its cost decisions.
| Layer | Virtual Machines | App Service |
|---|---|---|
| Datacenter and hardware | Microsoft | Microsoft |
| Operating system patching | You | Microsoft |
| Web server and runtime | You | Microsoft for built-in stacks, you for custom containers |
| Load balancing and TLS front door | You | Microsoft |
| Application code and settings | You | You |
| Identity, data and network design | You | You |
Because the platform patches the operating system for you, your instances can be restarted or moved to other machines at any time. Designing for that reality, instead of fighting it, is the foundation of every good App Service architecture.
Where App Service Fits in the Azure Family
Azure offers several places to run code. Virtual machines give maximum control and maximum chores. Azure Kubernetes Service gives container orchestration for large, many-part systems. Azure Container Apps gives a simpler container platform with event-driven scaling. Azure Functions gives small pieces of code that run on triggers. App Service sits in the comfortable middle: it is the most direct path for a typical web application that needs to be reliable, secure and easy to release.
2Core Concepts and Vocabulary
Before going deeper, we need a shared language. These eight terms appear in every conversation about App Service.
App Service Plan
The set of virtual machines, with a chosen size and price tier, that runs your apps. The plan is what you actually pay for, not the individual apps.
Web App
One application hosted inside a plan. It could be a website, an API or a container. Several apps can share one plan.
Instance
A single virtual machine in the plan. Scaling out means adding instances. Every app in the plan runs on every instance.
Deployment Slot
A live, separately addressable copy of your app, such as staging, that shares the plan and can be swapped with production.
Front End
A platform-managed server that receives incoming web requests and forwards them to a worker running your app. It is the doorman of the building.
Worker
The virtual machine instance that actually executes your code. It is the kitchen where the cooking happens.
Kudu (SCM Site)
A hidden management site attached to every app, used for deployment, file browsing, process inspection and diagnostics.
ARR Affinity
A cookie that sticks a user to one instance. It is on by default and has big consequences for scaling, as we will see later.
The Plan Is the Real Unit of Compute
Beginners often think each app has its own servers. It does not. The plan owns the servers. When you place three apps in one plan, all three run side by side on every instance in that plan, and they compete for the same CPU and memory. This explains both the main saving of App Service, because many small apps can share one set of machines, and its main risk, because one greedy app can slow down its neighbors.
An App Service plan is like an apartment building you rent a floor in. The apps are the families living on that floor. They share the water pressure and the elevator. If one family runs ten washing machines at once, everyone else notices.
Control Plane and Data Plane
Two words appear often in Azure architecture. The control plane is how you manage resources: creating a plan, changing a setting, scaling out, all through the Azure Resource Manager. The data plane is how users actually use your app: requests flowing in and responses flowing out. These two planes have different permissions, different logs and different failure modes. A broken control plane does not necessarily stop your running site, and a flood of user traffic does not stop you from changing a setting.
Many people believe that deleting an app also removes the plan and stops billing. It does not. An empty plan with running instances is still billed. Always check for forgotten plans after cleaning up apps.
3Architecture and Components
A look at the machinery that sits between a visitor and your code.
The Big Picture
In the public multitenant service, many customers share a large pool of infrastructure called a stamp or scale unit. Inside it, specialized roles cooperate. Front ends accept traffic. Workers run apps. A management layer handles deployment and configuration. A shared file service holds site content. A set of supporting services handles certificates, domain routing and monitoring. You never touch these roles directly, but knowing they exist explains many behaviors that otherwise look strange.
flowchart TD
U["Visitor Browser"] --> DNS["DNS Name of Your App"]
DNS --> FE["Platform Front Ends"]
FE --> W1["Worker Instance 1"]
FE --> W2["Worker Instance 2"]
FE --> W3["Worker Instance 3"]
W1 --> ST["Shared Content Storage"]
W2 --> ST
W3 --> ST
MGMT["Management and Deployment Layer"] --> W1
MGMT --> W2
MGMT --> W3
ARM["Azure Resource Manager"] --> MGMT
Front Ends: The Doormen
Front ends terminate incoming connections, handle TLS, apply access restriction rules, and pick a worker to receive each request. They use a routing technology often called Application Request Routing. They are shared by many customers in the multitenant service, which is why your app cannot choose or tune them. In an App Service Environment, which we cover in a later chapter, the front ends are dedicated to you.
Workers: The Kitchens
A worker is a virtual machine of the size you chose in your plan. On it, a sandbox or a container runs your app. For Windows, a process isolation model keeps apps in the same plan separated from each other. For Linux, each app runs in its own container. The worker also runs small platform agents that report health, collect logs and apply configuration changes.
Content Storage: The Pantry
Your app files live on a shared network file system that every instance in the plan can read. This is why all instances see the same files and why a deployment lands everywhere at once. It also explains an important performance fact: reading files over a network is slower than reading from a local disk. Platform features such as running from a deployment package exist largely to reduce this cost.
Management Layer
Applies configuration, receives deployments and coordinates restarts across instances.
Resource Manager
The Azure-wide control plane that authenticates you and routes your management commands to the right service.
Certificate and Domain Services
Store certificates, bind custom domains and keep TLS working at the front end.
Telemetry Pipeline
Gathers metrics and logs from instances and sends them to Azure Monitor and your chosen destinations.
Treat every instance as disposable. Anything important must live outside the instance: in a database, in blob storage, in a cache, or in the shared content area for read-only assets. This one rule prevents most surprises.
4Internal Working: The Journey of One Request
Following a single click from the browser to your code and back reveals where time and failures hide.
sequenceDiagram
participant B as Browser
participant D as DNS
participant F as Front End
participant W as Worker Instance
participant A as Your App
B->>D: Look up myapp.azurewebsites.net
D-->>B: Address of the stamp
B->>F: HTTPS request
F->>F: Check TLS, rules, restrictions
F->>W: Forward to chosen instance
W->>A: Deliver request to app process
A-->>W: Response
W-->>F: Response
F-->>B: Response over TLS
Name Resolution
The browser asks DNS where your app lives. A default azurewebsites.net name or your own custom domain resolves to the platform stamp, or to a private address if you use private networking.
TLS Handshake at the Front End
The front end presents the certificate that matches the host name. Your app never has to handle certificates itself, which removes a whole class of mistakes.
Rule Evaluation
The front end checks access restrictions, such as allowed IP ranges or required headers. Blocked requests are rejected here, before they cost your workers any CPU.
Instance Selection
The front end picks a healthy worker. If ARR Affinity is on and a cookie is present, it prefers the instance that served the user before. Otherwise it spreads load across instances.
Execution in the App Process
The worker hands the request to your running process. If the process is not yet started, a cold start happens first, which adds noticeable delay.
Response and Logging
The response travels back the same way. Platform logs, metrics and any Application Insights data are recorded along the route.
Cold Starts and Always On
On paid tiers there is a setting called Always On. Without it, an app that receives no traffic for a while may be unloaded to save resources, and the next visitor pays the cost of loading it again. With Always On, the platform sends regular pings so the app stays warm. Production apps almost always want this enabled, and it needs a tier above the shared ones.
A cold start is like a shop that turns off its lights and locks the cash register when no customers are around. The first person to walk in must wait while the owner switches everything on. Always On is the owner who keeps the lights on all day.
The Request Timeout Reality
The platform front end does not wait forever. A long-running request can be cut off by the load balancer after a fixed idle period, even if your code is still working. This means that long jobs belong in a background process, a queue consumer or a separate worker service, not inside a web request. Designing your web layer to answer quickly and hand heavy work elsewhere is both cheaper and safer.
Running a report that takes ten minutes directly inside an HTTP request. The browser sees a timeout error even though the work may complete on the server, and users retry, doubling the load. Use a queue and a status page instead.
5App Service Plans and Pricing Tiers
The plan you choose decides your features, your limits and your bill.
What a Plan Defines
Every plan fixes four things: the operating system, the region, the number of instances and the size and tier of those instances. The tier controls which features you receive. Because the plan is a billing unit, you pay for every instance in it, whether or not your apps are busy.
The Tier Families
| Family | Typical Tiers | Compute Type | Best For |
|---|---|---|---|
| Shared compute | Free, Shared | CPU quota on a shared virtual machine, no scale-out | Learning and quick experiments only |
| Dedicated compute | Basic, Standard, Premium v2, v3 and v4 | Dedicated virtual machines for your plan | Most real workloads |
| Isolated | Isolated v2 and Isolated v4 inside an App Service Environment | Dedicated machines on a dedicated virtual network | Strict compliance, very high scale, full network control |
Free and Shared: Playground Only
These tiers run on machines shared with other customers, give your app only a daily CPU time allowance, cannot scale out and carry no service level agreement. Use them for tutorials, never for anything customers depend on.
Basic: Small and Steady
Dedicated machines, custom domains with certificates and manual scale-out. Basic suits low-traffic internal tools and early prototypes that do not need advanced traffic management. It does not include rule-based autoscale or deployment slots.
Standard: The First Production Tier
Adds autoscale rules, deployment slots, backups and traffic routing features. Many small production sites live happily here.
Premium: Performance and Reach
Newer machine generations, more memory per core, more slots, faster scale-out, zone redundancy options and the newer automatic scaling feature. Premium v3 is a widely used workhorse, and Premium v4 brings the latest platform generation, including memory-optimized sizes aimed at memory-hungry apps. Which generation and size you can use depends on your region and operating system, so always check current availability.
Isolated: Your Own Private Building
Runs inside an App Service Environment, a single-tenant deployment inside your own virtual network. It offers the highest scale limits and complete network isolation, at a higher cost and with more design effort.
Sizes Inside a Tier
Each tier offers several sizes, usually named with a letter and a number, such as a small, medium or large option. Larger sizes bring more virtual CPUs and more memory per instance. Some families add a memory-optimized variant that gives extra memory for the same number of cores, which is helpful for apps that cache a lot of data in-process.
Plan Density: How Many Apps per Plan?
Plan density is the number of apps you pack into one plan. High density saves money because idle capacity is shared. Low density protects apps from each other. A practical rule is to group apps that belong to the same product, have similar traffic patterns and can tolerate sharing fate. Isolate an app in its own plan when it is resource-hungry, needs to scale on its own, needs a different region or operating system, or belongs to a different security boundary.
Scale up means picking a bigger machine size or higher tier. Scale out means adding more instances of the same size. Scale up is a vertical move for more power per instance and new features. Scale out is a horizontal move for more capacity and resilience. Healthy production systems usually do both: a sensible size, then several instances.
Scaling up is replacing your delivery bike with a bigger van. Scaling out is hiring more bikes and riders. The van is stronger but is still a single point of failure. More riders can keep delivering even if one of them has a flat tire.
Advantages of Sharing a Plan
- Lower total cost for many small apps
- One place to scale, monitor and size
- Idle capacity is used by whoever needs it
- Simpler governance for one product team
Trade-offs of Sharing a Plan
- A noisy app can slow every neighbor
- All apps scale together, not independently
- An overloaded plan can cause downtime for new and existing apps
- Different security boundaries are harder to separate
6Runtimes, Operating Systems, Containers and the File System
Choosing how your app is packaged shapes its performance, its portability and its storage behavior.
Windows or Linux
A plan is tied to a single operating system, so Windows apps and Linux apps live in separate plans. Linux is the common choice for Node.js, Python, Java, PHP and containerized workloads, and it is often cheaper. Windows remains important for classic .NET Framework applications and for features that rely on Windows-specific behavior. For new .NET work using modern versions, both work well, and the decision usually comes down to team skills and existing tooling.
Code or Container
Deploy as Code
You hand over your built files and pick a runtime version. Microsoft supplies the base image, patches it and updates minor runtime versions on a schedule. Least effort, least control.
Deploy as Container
You build an image with exactly the packages you need and point the app at a registry. Most control and portability. You also own patching of everything inside the image.
Deploying as code is like staying in a furnished hotel room: the bed, towels and cleaning are included, and you bring a suitcase. Deploying as a container is like shipping your own furniture in a moving truck: the room looks exactly how you like it, but you must also dust it.
Where Files Live and Why It Matters
App Service gives each app a persistent content area backed by network storage, shared by all instances. On Linux, only that content area is persistent by default, and the rest of a container file system disappears when the container restarts. On Windows, a similar split exists between the shared content folder and temporary local disk space. If your code writes uploads, caches or session files to the wrong place, you will see data vanish after a restart or differ between instances.
| Location | Survives Restart | Shared by Instances | Good For |
|---|---|---|---|
| Persistent content area | Yes | Yes | Deployed files, small shared assets |
| Local temporary disk | No | No | Scratch work, temporary caches |
| Blob storage or database | Yes | Yes, by design | User uploads, durable data |
| Distributed cache | Depends on config | Yes | Sessions, hot data |
Running from a Package
A popular platform feature lets the app run directly from a single compressed deployment package instead of from thousands of loose files. This reduces slow file reads over the network, makes deployments atomic, since the package is swapped in as one piece, and lowers cold start time. The trade-off is that the app folder becomes read-only, so anything that writes into its own directory must be redesigned.
Storing user profile pictures on the web server disk. With two instances, user A uploads to instance one, and user B sees a broken image when routed to instance two. Always send uploads to blob storage.
Startup Behavior and Health of the Process
When an instance starts your app, the platform waits for the process to begin listening on the expected port and to answer a first request. On Linux containers, the app must listen on the port the platform expects, and you can tell the platform which port to use through a setting. If the app crashes during startup, takes too long to respond, or listens on the wrong port, the platform restarts it repeatedly and you see errors that look like random downtime. Slow startup is especially painful during scale-out, because a new instance that needs two minutes to wake up is useless during a sudden spike. Keep startup work small: load configuration, open connections lazily and defer heavy cache warming to a background task.
Windows Sandbox Versus Linux Container Isolation
The two operating systems isolate apps differently. On Windows, every app runs inside a restricted sandbox that limits what the process can do on the machine, such as which system calls and network ports it can use. Some old libraries that depend on unusual system features, like certain graphics or printing components, simply cannot run there. On Linux, each app runs in its own container with its own file system view, which feels more natural to people who already use containers. Neither model is better in every situation. The right question is which model matches the libraries and behaviors your code truly needs.
Test your app on the exact operating system and plan size you intend to use in production, not just on a laptop. Many surprises, such as missing fonts, different file name case rules or lower memory limits, appear only after deployment.
7Deployment and Release Engineering
Shipping new versions without scaring your users is where App Service shows its strengths.
Ways to Deploy
App Service accepts releases from many sources: continuous integration pipelines such as GitHub Actions or Azure DevOps, zip packages pushed by command line tools, container registries with automatic pull on a new image, local Git, and developer tools inside code editors. Mature teams almost always choose a pipeline, because it makes every release repeatable, reviewed and traceable to a commit.
Build and Test
The pipeline compiles the code, runs automated tests and produces one immutable package or image. The same artifact travels through every environment.
Deploy to the Staging Slot
The artifact is released to a slot that has production-like settings but no live users yet.
Warm Up and Verify
Automated smoke tests hit the slot. The app loads caches, opens connections and proves it is healthy.
Swap into Production
The platform exchanges the slot with production. The routing change is nearly instant, and the old version moves into the staging slot.
Watch and Roll Back if Needed
If metrics worsen, swap again. The previous version is still warm in the other slot, so rollback takes seconds.
How Deployment Slots Really Work
A slot is a full live app with its own host name, sharing the plan’s machines. When you swap, the platform first applies the target slot’s settings to the source slot instances, restarts them, waits for them to respond, and only then redirects traffic. Because the new version is already warm when users arrive, there is no cold start storm. Slots are available from the Standard tier upward, with higher tiers allowing more of them.
flowchart LR
CI["Pipeline Artifact"] --> S["Staging Slot"]
S --> T["Smoke Tests and Warm Up"]
T --> SW["Swap Operation"]
SW --> P["Production Slot"]
P --> OLD["Previous Version Now in Staging"]
OLD -.-> RB["Rollback by Swapping Again"]
RB -.-> P
Slots are like a theater with a stage and a rehearsal room. The new play is fully rehearsed backstage with real costumes. When it is ready, the curtain rotates and the audience sees the finished show, with no awkward gap.
Slot-Specific Settings
Some settings should follow the code, while others should stay with the environment. A database connection string for staging should not move into production during a swap. App Service lets you mark individual settings as slot-specific, often called sticky. Settings that are not sticky travel with the swap. Forgetting this distinction is a classic cause of a staging database being used by live users.
Testing in Production with Traffic Routing
Instead of an all-or-nothing swap, you can route a small percentage of production traffic to a slot. If errors stay low, you increase the share gradually, which is a canary release. Users can also be pinned to a slot for a session so they have a consistent experience. Note that the automatic scaling feature does not apply to slot traffic, so plan capacity with that in mind.
Problem
Teams deploy directly into the production slot, because it is quicker for small fixes.
Why It’s Harmful
Files are replaced while live users are connected, the app restarts cold, and there is no instant rollback. A single bad release becomes a visible outage.
Correct Approach
Always deploy to a non-production slot, validate it, then swap. Make this the only path to production through your pipeline permissions.
Warm-up and Auto Swap
During a swap, the platform sends requests to the root of the source slot and waits for a successful response before moving traffic. You can customize this warm-up so that it requests specific paths, which is useful when the first page does not touch your database, caches or search service. An optional auto swap feature performs the swap automatically after each successful deployment to a slot. It is convenient for simple projects, but mature teams often prefer a manual or pipeline-controlled swap so that smoke tests and approvals can run first.
Databases and Backward Compatibility
Slots swap application code, not databases. Both slots usually point at the same database, or at different ones, and a release that changes the database structure must therefore work with both the old and the new code for at least a short time. The safe approach is called expand and contract. First you add new columns or tables in a way that old code ignores. Then you release the new code that uses them. Only much later do you remove the old structures once nothing depends on them. If you rename a column in one step, the old version in the other slot breaks the moment the change lands, and your instant rollback is no longer instant.
Changing a database during a live release is like replacing a bridge while traffic is still crossing. You build the new lane beside the old one, move cars over, and only then demolish the old lane. Tearing up the road first would trap everyone in the middle.
What a Swap Does Not Fix
A swap gives you a quick way to undo code. It does not undo data written by the new version, messages already put on queues, emails already sent or external systems already called. Plan for these side effects with feature flags, idempotent operations and careful release ordering, so that a rollback leaves the world in a consistent state.
8Configuration, Secrets and Identity
Good applications keep code, settings and secrets in three separate places.
Application Settings
App settings are named values that the platform injects into your app as environment variables. They let the same code behave differently in development, staging and production without any rebuild. They are encrypted at rest by the platform and are editable without redeploying. Connection strings work similarly, with a type label that some frameworks use.
Key Vault References
Secrets such as database passwords should not be pasted into app settings. Instead, a setting can hold a reference that points to a secret stored in Azure Key Vault. At runtime the platform fetches the real value using the app’s managed identity and substitutes it. The secret never appears in your repository, your pipeline logs or the configuration blade. Rotation becomes a Key Vault task instead of a code change.
Managed Identity
A managed identity is an automatically managed account for your app inside Microsoft Entra ID. You never see or rotate its credentials, because Azure handles them. You grant that identity permission on a target resource, such as a database, a storage account or a vault, and the app can call it without any password. A system-assigned identity lives and dies with the app. A user-assigned identity is a standalone resource that several apps can share, which is useful for slots, since each slot would otherwise have its own system identity.
A password in a config file is like a house key hidden under the doormat: anyone who finds the mat has the key. A managed identity is like a smart lock that recognizes the resident. There is no key to lose, copy or forget to change.
flowchart LR
APP["Your App"] -->|"asks for token"| MI["Managed Identity Endpoint"]
MI --> ENTRA["Microsoft Entra ID"]
ENTRA -->|"short lived token"| APP
APP -->|"calls with token"| KV["Key Vault"]
APP -->|"calls with token"| SQL["Database"]
APP -->|"calls with token"| BLOB["Blob Storage"]
Built-in Authentication
App Service has a feature, often called Easy Auth, that handles sign-in in front of your code using providers such as Microsoft Entra ID. It verifies who the caller is and passes identity information to your app. It does not decide what that person may do. Role checks and business rules, called authorization, still belong in your application.
Use separate identities and separate vaults per environment. A staging app should never hold permissions on production data, even by accident.
Problem
Database passwords and API keys sit in plain app settings or even in source control.
Why It’s Harmful
Anyone with read access to the configuration or the repository can steal them. Rotating them requires coordinated changes across apps.
Correct Approach
Prefer managed identities for Azure services, and Key Vault references for secrets that must exist. Limit who can read vault contents.
9Scaling: Manual, Autoscale and Automatic Scaling
Scaling is not one feature. It is three, with different rules, different tiers and different traps.
Three Ways to Scale Out
| Aspect | Manual | Autoscale | Automatic Scaling |
|---|---|---|---|
| Available from | Basic | Standard | Premium v2 and above |
| Decision basis | You pick a number | Metric rules and schedules | Incoming HTTP traffic |
| Always-ready instances | Not applicable | No | Yes, minimum of one |
| Prewarmed instances | No | No | Yes, one by default |
| Per-app limits | No | No | Yes |
Autoscale in Detail
Autoscale is a rule engine from Azure Monitor. You define conditions such as: when average CPU stays above a threshold for several minutes, add an instance; when it stays low, remove one. You can also create schedules, for example more capacity on weekday mornings. Autoscale works at the plan level, so every app in the plan scales together.
Automatic Scaling in Detail
Automatic scaling is a newer, traffic-driven option. You do not write rules. The platform watches incoming HTTP load and adds instances, keeping at least one always-ready instance and one prewarmed instance so that sudden spikes do not suffer cold starts. You can set a maximum burst for the plan and limits for individual apps, so a busy app cannot swallow the entire plan. Billing is per second for each instance, including prewarmed ones. Only one scaling method should be active on a plan at a time, and automatic scaling is switched off if web apps and function apps share the same plan.
Autoscale is a supermarket manager who follows a written policy: if queues exceed five people for ten minutes, open another till. Automatic scaling is a manager who watches the doorway and opens tills the moment a crowd appears, always keeping one extra cashier standing ready.
The ARR Affinity Trap
ARR Affinity pins a user to one instance by a cookie. That is handy for apps that keep session data in memory, but it undermines scaling: new instances receive only brand-new visitors, while existing users keep hammering the old instance. When automatic scaling is enabled, the platform turns off affinity for existing apps for exactly this reason. The deeper fix is to make your app stateless, with sessions in a distributed cache, so any instance can serve any user.
Scaling to ten instances while ARR Affinity is on and noticing that one instance stays at ninety percent CPU. The extra machines are simply not receiving the existing users. Check affinity before buying more capacity.
Designing Good Autoscale Rules
Scale Out Fast, In Slowly
Add capacity after a short sustained spike. Remove it only after a longer calm period to avoid flapping.
Leave a Gap Between Thresholds
If scale-out triggers at seventy percent CPU, scale-in should trigger well below, so the system does not oscillate.
Use a Cool-down Period
Give new instances time to start and take load before another decision is made.
Set Sensible Minimums and Maximums
A minimum of two instances protects availability. A maximum protects your wallet and your databases.
Do Not Forget the Dependencies
Scaling the web tier does nothing if the database is the bottleneck. Ten instances opening a hundred connections each can crush a small database. Always scale and tune dependent services together, and use connection pooling and caching to reduce pressure.
Instance Limits and Why They Matter
Every tier has a ceiling on how many instances a plan can reach, and those ceilings rise as you move up the tiers. Standard allows a modest number, Premium allows far more, and an App Service Environment allows the most. These are not just trivia. If your launch plan expects a big marketing event, check the limit for your tier and region well in advance, because raising capacity at the last minute can be blocked by quota or by regional availability of the machine size you want. Requesting extra quota early is far easier than negotiating it during an incident.
A Simple Method for Capacity Planning
Measure One Instance
Run a load test against a single instance and find the request rate at which latency starts to rise sharply. This is its comfortable capacity, usually well below its absolute maximum.
Estimate Peak Demand
Use past traffic, marketing calendars and growth trends to estimate the busiest minute you expect, then add a safety margin.
Divide and Add Redundancy
Divide peak demand by comfortable capacity, then add at least one extra instance so that losing a machine does not hurt.
Verify the Dependencies
Check that your database, cache and external APIs can handle the same peak, including the number of simultaneous connections.
Rehearse
Repeat the test at the target scale in a safe environment and watch how fast new instances join and how the database reacts.
Watch the time between the scale decision and the moment a new instance actually serves traffic. If this delay is longer than your typical spike, pre-scale on a schedule or choose a mode with always-ready and prewarmed instances.
10Networking Deep Dive
Inbound and outbound traffic follow separate paths, with separate features. Mixing them up causes many outages.
Inbound and Outbound Are Different Problems
Inbound networking answers who can reach my app. Outbound networking answers what my app can reach. In the multitenant service, these are handled by different features that you enable per app. Understanding which feature solves which direction is the key to a correct design.
Access Restrictions
Allow or deny rules based on IP ranges, virtual network subnets or service tags, evaluated at the front end for the public address.
Private Endpoint
Gives your app a private IP address inside your virtual network. With public access disabled, the app has no internet-facing address at all.
Regional VNet Integration
Lets your app make outbound calls into a virtual network through a delegated subnet, so it can reach private databases and vaults.
NAT Gateway
Provides a stable, predictable outbound IP address when combined with virtual network integration, which partners often need for allow lists.
Hybrid Connections
A relay-based way to reach a single on-premises host and port without opening inbound firewall holes.
Front Door or Application Gateway
Services placed in front of the app for global routing, web application firewall rules and caching.
Private Endpoint Plus VNet Integration
A fully private design uses both features together. A private endpoint carries inbound traffic from your internal network to the app. Virtual network integration carries the app’s outbound traffic to private resources. They use different subnets: the integration subnet must be delegated to the App Service platform and cannot be the same subnet that holds a private endpoint. Both features require at least the Basic tier.
flowchart TD
USER["Internal User or Front Door"] --> PE["Private Endpoint Subnet"]
PE --> APP["App Service"]
APP --> INT["Integration Subnet delegated to App Service"]
INT --> FW["Hub Firewall or NAT Gateway"]
INT --> DB["Private Database"]
INT --> KV["Key Vault with Public Access Off"]
FW --> EXT["External Partner API"]
DNS["Private DNS Zone for azurewebsites"] -.-> PE
A private endpoint is a private side door added to your building that only employees with a badge can see from the inside corridor. Virtual network integration is the staff-only tunnel your workers use to reach the warehouse next door. The front door on the street can then be bricked up completely.
DNS: The Silent Troublemaker
Private endpoints depend on correct private DNS. The app’s normal public name must resolve to the private IP address when queried from inside your network. This is done with a private DNS zone linked to your virtual networks. If DNS is wrong, clients quietly reach the public address, which is blocked, and you see confusing timeouts. Many private networking incidents are really DNS incidents.
Traffic arriving through a private endpoint bypasses the normal access restriction rules. Protect it with network controls such as subnet security groups, and do not assume your IP allow list covers private traffic.
Outbound IP Addresses
In the multitenant service, an app calls out from a shared set of addresses that may change when you scale or change tiers. If a partner requires a fixed address, route outbound traffic through a NAT gateway or a firewall attached to your integration subnet. Never hard-code the list of outbound addresses shown in the portal and expect it to stay constant.
Service Endpoints Versus Private Endpoints
Two features are often confused because both involve virtual networks. A service endpoint makes traffic from a subnet to an Azure service travel over the Azure backbone, and it lets the service recognize that subnet as an allowed source. The service still has a public address, though. A private endpoint is different: it creates a network card with a private address for one specific resource, and the resource can then turn its public access off completely. Service endpoints are simpler and free of extra charges, while private endpoints give stronger isolation and work across peered and connected networks, at an added cost and with more DNS work.
| Question | Service Endpoint | Private Endpoint |
|---|---|---|
| Does the resource keep a public address? | Yes, but it can be restricted to your subnet | Public access can be switched off entirely |
| Is a private IP created? | No | Yes, inside your subnet |
| DNS changes needed? | Usually none | Yes, private DNS is required |
| Reachable from on-premises networks? | Generally not | Yes, through VPN or private circuits |
| Extra cost? | No additional charge | Hourly and data processing charges |
Sending All Outbound Traffic Through the Network
By default, only calls to private address ranges travel through the integration subnet, while calls to the public internet leave directly from the platform. If your organization requires every outbound call to pass through a central firewall for inspection and logging, you can configure the app to send all outbound traffic through the virtual network and attach a route table that points to the firewall. This is the standard way to enforce egress control, but it adds a point of failure and a cost, and it can break calls to platform services if the firewall rules are too strict. Always test deployments, certificate renewals and log delivery after tightening egress.
Forcing all outbound traffic through a firewall without allowing the platform’s own management and storage endpoints. The app then fails to start, pull containers or write logs, and the symptom looks like a broken deployment rather than a firewall rule.
Subnet Planning
The integration subnet needs enough addresses for every instance of every plan that uses it, plus room to scale and for platform needs during updates. Subnets that are too small cause scale-out to fail in confusing ways. Private endpoint subnets also need space, with one address for each endpoint. Plan address ranges early, document them, and avoid overlapping ranges with on-premises networks, because overlaps make later connections painful or impossible.
11App Service Environment v3: Your Own Private Building
When sharing a stamp with other customers is not acceptable, an App Service Environment gives you a single-tenant deployment inside your own virtual network.
What It Is
An App Service Environment, often shortened to ASE, is a fully isolated and dedicated deployment of App Service that runs in a single subnet of your virtual network. Apps live in plans, and the plans live inside the environment. The front ends and workers belong to you alone. Apps in the environment can reach other resources in the same virtual network with no extra features turned on, because they already sit inside it. The current generation, version 3, works with the Isolated v2 plans and a newer Isolated v4 generation is also offered.
The multitenant service is a shared office floor with partitions and badge readers. An App Service Environment is renting your own building: the neighbors are gone, the walls are yours, and you decide who walks through the lobby.
Why Teams Choose It
Network Controls Outside the App
In the shared service, each app must individually enable networking features, and someone with the right permissions could change them. In an ASE, network access control exists at the environment boundary, outside of any single app’s configuration.
Compliance and Isolation
Regulated industries often need single-tenant hosting. If hardware-level isolation is required, the environment can be deployed onto dedicated hosts.
High Scale
A single version 3 environment supports up to two hundred instances across all its plans, and one Isolated v2 plan supports up to one hundred instances.
Internal-Only Applications
With an internal virtual IP, every app gets an address inside your subnet and nothing is exposed to the internet. Apps in an internal ASE can even be reached across global virtual network peering, which was not possible in earlier versions.
Key Design Facts
| Topic | What to Know |
|---|---|
| Subnet size | A /24 block with 256 addresses is recommended so the environment can scale to its full limit. Some infrastructure roles scale automatically and consume addresses. |
| Network dependencies | Version 3 has no networking dependencies on your virtual network, so you can secure and route all inbound and outbound traffic as you wish. |
| Front-end scaling | Handled automatically, with no manual tuning needed. |
| Scale operations | Scaling no longer blocks other scale operations. Only one operation at a time applies to a given combination of operating system and size. |
| Zone redundancy | Optional where all dependencies support it, with no extra charge for availability zone support. Each plan needs enough instances to spread across zones. |
| Dedicated hosts | An option for physical isolation. Deployments on dedicated hosts are not zone redundant and are limited by available cores. |
| Empty environment cost | An environment with no instances is charged as if one small Windows instance were running. |
| Removed features | Some older capabilities, such as backup and restore with firewall-protected storage accounts, are not available. |
An ASE is powerful but not free of effort. If your only requirement is private access, the multitenant service with a private endpoint and virtual network integration may be enough and far cheaper. Choose an ASE when you truly need single-tenant isolation, environment-level network control or very high scale.
Advantages
- Single-tenant compute and network isolation
- Network rules enforced outside app configuration
- Highest scale limits in App Service
- Option for dedicated hardware
- Faster, non-blocking scale operations in version 3
Disadvantages / Trade-offs
- Higher baseline cost, even when idle
- Needs a dedicated subnet and careful IP planning
- Some older features unavailable
- More network design and operations effort
12Security: Defense in Depth
No single switch makes an app secure. Layers do.
A castle is not protected only by its gate. It has a moat, walls, guards, locked doors and a vault. If one layer fails, the next one still holds. Cloud security works the same way.
Layer 1: The Edge
Place Azure Front Door or Application Gateway with a web application firewall in front of internet-facing apps. These filter common attacks such as injection attempts and abusive bots, absorb traffic spikes and provide global routing. Then restrict the app so it accepts traffic only from that edge service, not directly from the internet.
Layer 2: Transport Security
Enable the HTTPS-only setting so plain HTTP requests are redirected. Set a minimum TLS version so outdated, weak protocol versions are refused. App Service Managed Certificates give free certificates for custom domains, and you can import your own for wildcard or extended needs. The platform handles renewal for managed certificates.
Layer 3: Identity and Access
Use Microsoft Entra ID for user sign-in and managed identities for service access. Control who can manage the app with role-based access control, giving people the least privilege they need. A developer who only reads logs should not be able to change networking.
Layer 4: Management Surface
Every app has a management site and optionally file transfer endpoints. Disable basic authentication, meaning username and password publishing credentials, where you can, and use identity-based deployment instead. Turn off remote debugging in production. Restrict access to the management site separately from the main site if your design needs it.
Layer 5: Data and Secrets
Keep secrets in Key Vault, use private endpoints for databases and storage, and encrypt data in transit and at rest. Avoid logging sensitive values.
Layer 6: Detection and Response
Microsoft Defender for App Service can alert you about suspicious activity. Send diagnostic logs to a central workspace and set alerts on unusual spikes of errors or blocked requests.
HTTPS Only
Redirect all HTTP traffic to HTTPS automatically.
Minimum TLS
Refuse old protocol versions that have known weaknesses.
Managed Identity
Prefer it over passwords for every Azure service call.
Private Access
Use private endpoints for data stores and, where suitable, for the app.
Locked Management
Disable shared publishing credentials and remote debugging.
Central Logging
Stream platform and app logs to a workspace with alerts.
Built-in authentication proves who the caller is, but it does not decide what they may do. An authenticated user is not automatically an authorized one. Enforce roles and permissions inside your application logic.
Problem
The app is placed behind a web application firewall, but its original public address is still open to the whole internet.
Why It’s Harmful
Attackers find the direct address and bypass the firewall completely, making the protective layer decorative.
Correct Approach
Restrict inbound access so only the edge service, or a private endpoint, can reach the app.
Cross-Origin Rules and Security Headers
Browsers block web pages from calling APIs on other domains unless the API explicitly allows it, a rule called cross-origin resource sharing. App Service lets you configure allowed origins at the platform level, but many teams handle it inside the application instead. Whichever you choose, do not use a wildcard that allows every origin for APIs that carry user data. In addition, send modern security headers, such as those that force HTTPS, block the page from being framed by other sites and restrict where scripts may load from. These small settings stop whole categories of browser attacks.
Thinking Like an Attacker
A useful design review asks four plain questions. How can someone reach this app from outside? What can someone do if they take over this app? What secrets or data does it hold or reach? How would we notice if it happened? For App Service, the answers usually lead to the same improvements: close direct public access, give the identity only the permissions it needs, keep data stores private, and send logs and alerts to a place the attackers cannot erase.
Least Privilege Identity
An app that only reads from one storage container should have a role that allows reading that single container, not owner rights on the whole subscription. If the app is ever compromised, the damage stays small.
Separate Environments
Development, staging and production should live in different resource groups or subscriptions, with separate identities and vaults, so that a leak in one never grants access to another.
13Reliability, Availability and Disaster Recovery
Reliability is the art of staying useful when something breaks, because something always breaks.
Service Level Basics
Paid dedicated tiers come with a service level agreement for availability, while the Free and Shared tiers carry none. Remember that the platform guarantee covers the platform, not your code, your database or your configuration mistakes. Your real availability is the combined result of every dependency in the chain.
Single Instance Is a Single Point of Failure
A plan with one instance goes down during platform maintenance, a restart or a machine fault. Running at least two instances lets the platform route around a failing one. Health Check makes this smarter: you tell the platform a path to probe, and instances that keep failing are pulled out of rotation and replaced. This works best when you have more than one instance to shift traffic to.
Availability Zones
An availability zone is a physically separate datacenter within a region, with independent power, cooling and networking. A zone-redundant plan spreads instances across zones so that the loss of a whole datacenter does not take your app down. It requires a supported tier and region and a minimum number of instances so there is something in each zone. It protects against zone failure but not against a whole region failure.
Multi-Region Designs
For regional outages or global audiences, run the app in two regions and place a global router in front, such as Azure Front Door or Traffic Manager. You can run both regions actively or keep one on standby. Data replication is the hard part: your database or storage must replicate across regions, or the second region has nothing to serve.
flowchart TD
U["Global Users"] --> FD["Front Door or Traffic Manager"]
FD --> R1["Region A App Service Plan"]
FD --> R2["Region B App Service Plan"]
R1 --> D1["Primary Database"]
R2 --> D2["Replica Database"]
D1 -. replication .-> D2
R1 --> M["Central Monitoring Workspace"]
R2 --> M
Backups and Recovery Targets
App Service can back up app content and configuration on supported tiers. A backup is only useful if you have practiced restoring it. Two numbers guide every recovery plan: the recovery time objective, which is how long you can be down, and the recovery point objective, which is how much recent data you can afford to lose. Pick the cheapest design that meets those numbers, not the fanciest one.
| Design | Protects Against | Cost and Effort |
|---|---|---|
| Single instance | Nothing much | Lowest |
| Two or more instances | Instance fault and maintenance | Low |
| Zone-redundant plan | Datacenter failure in a region | Medium |
| Multi-region with global router | Region failure | High |
Rehearse failure on purpose. Stop an instance, break a dependency in a test environment, and watch how the system reacts. Documents about resilience are not the same as proof of resilience.
Planned Maintenance and Restarts
The platform periodically updates the machines under your app, patches operating systems and moves apps between hosts. During these events your instances may be restarted. This is normal and is a core reason to run at least two instances, handle shutdown signals gracefully, keep startup fast and avoid storing important state locally. A well-built app barely notices these events, while a fragile one produces a burst of errors every time the platform does routine work. Treat each restart as a free, frequent resilience test.
Graceful Failure for Dependencies
Reliability is not only about the platform. When your database is slow or an external API is down, your app should respond with a clear, limited failure rather than hang and consume every thread. Use timeouts on every outbound call, retries with delays that grow, and fallbacks such as cached data or reduced features. A site that says some features are temporarily unavailable keeps customers far happier than one that spins forever.
14Monitoring, Logging and Diagnostics
You cannot fix what you cannot see. Good observability turns a midnight panic into a calm investigation.
Three Kinds of Signals
Metrics
Numbers over time, such as CPU percentage, memory percentage, response time, request count, queue length and error counts. Cheap, fast, ideal for alerts.
Logs
Detailed records of events: web server requests, console output, application messages and platform events. Ideal for finding the exact cause.
Traces
The path of one request across several services, showing where the time went. Application Insights provides this through distributed tracing.
Metrics are the dashboard lights in a car, logs are the service history book, and traces are the dashcam footage of one bad trip. You want all three when something rattles.
The Metrics Worth Watching
At the plan level, watch CPU percentage and memory percentage, because they tell you whether your machines are healthy. At the app level, watch response time, request count, HTTP server errors in the five hundreds, and the HTTP queue length, which shows requests waiting for a free worker. A rising queue with high CPU means you need more capacity. A rising queue with low CPU usually means threads are blocked waiting on a slow dependency.
Platform Logs
Diagnostic settings let you send web server logs, console logs, application logs, platform logs and audit logs to a Log Analytics workspace, a storage account or an event hub. Centralizing them in one workspace lets you query across apps, correlate with database and gateway logs, and build dashboards. Live log streaming is handy for a quick look, but it is not a replacement for stored logs.
Application Insights
Application Insights adds deep application-level telemetry: request timing, dependency calls, exceptions, user flows and live metrics. It answers the questions the platform cannot, such as which database call made this page slow. Enable it early, because you want history on the day something goes wrong, not the day after.
Built-in Troubleshooting Tools
The portal includes a diagnostics area that analyzes common problems like high CPU, memory leaks, slow responses and failed deployments, with guided suggestions. The management site lets you look at running processes, environment variables and files. Together they often solve an issue in minutes without any external tooling.
Alert Fires
A metric alert tells you error rate or response time crossed a threshold. The alert text should name the app and link to a runbook.
Check Scope
Is it one app, one instance, one region or everything? Metrics split by instance reveal a single sick machine.
Correlate with Changes
Did a deployment, a scale event or a configuration change happen shortly before? Activity logs show this.
Find the Slow Dependency
Use traces to see whether the database, a cache, or an outside API caused the delay.
Fix, Verify, Learn
Apply the fix, confirm the metrics recover, and record what you learned so the next incident is shorter.
Alerting on every small blip until the team ignores all alerts. Alert on symptoms users feel, such as error rate and latency, and keep resource alerts as supporting signals.
Designing Alerts People Trust
An alert should answer three things at a glance: what is wrong, how bad it is and what to do first. Tie alerts to service level objectives, which are simple promises such as ninety-nine percent of requests succeed within two seconds. When the error budget is burning quickly, page someone. When it burns slowly, create a ticket for working hours. Resource alerts, such as high CPU or memory, are supporting signals that explain a symptom rather than the main reason to wake a person.
Urgent Page
Users are failing right now: high error rate, no healthy instances or failed health checks across the plan.
Working-hours Ticket
Slow trends: growing memory use, rising latency or certificates approaching expiry.
Capacity Warning
Scale-out approaching the plan maximum or the quota ceiling, so someone can raise limits calmly.
Security Signal
Unusual spikes in blocked requests, failed sign-ins or changes to network and identity settings.
Dashboards That Tell a Story
A good dashboard has a clear order: user experience first, then application health, then platform and dependencies. Put request rate, error rate and response time at the top, then instance counts and CPU or memory, then database and cache health. When an incident starts, anyone on the team should be able to read the dashboard from top to bottom and see where the story turns bad.
15Design Patterns and Anti-patterns
Patterns are proven shapes that solve recurring problems. Anti-patterns are the shapes that keep causing incidents.
Helpful Patterns
Stateless Web Tier
Keep no important data in the instance. Sessions go to a distributed cache, files go to blob storage, and state goes to a database. Any instance can then serve any user, which unlocks scaling and fast recovery.
Queue-Based Load Leveling
The web app puts heavy work on a queue and returns quickly. A background worker processes the queue at its own pace. Spikes are absorbed by the queue instead of crashing the site.
Blue-Green Releases with Slots
Run the new version beside the old one, validate it, and swap. Roll back by swapping again.
Backend for Frontend
Give each client type, such as the web app and the mobile app, its own thin API app tailored to its needs. Each can scale and release separately.
Hub and Spoke Networking
Place shared firewalls, DNS and connectivity in a central hub network, and connect each workload network as a spoke. App Service integrates through private endpoints and integration subnets.
Circuit Breaker and Retry with Backoff
When a dependency fails, stop hammering it. Retry with growing delays and open a breaker so the app fails fast and recovers gracefully.
Anti-patterns to Avoid
Problem
Every app in the company is placed into one giant plan for maximum savings.
Why It’s Harmful
One memory leak or traffic burst slows or crashes dozens of unrelated apps, and scaling cannot be tuned per workload.
Correct Approach
Group apps by product, traffic shape and risk level. Isolate heavy or critical apps in their own plans.
Problem
The app depends on sticky sessions and local memory to remember users.
Why It’s Harmful
Scaling becomes uneven, restarts log everyone out, and instance failure destroys user state.
Correct Approach
Move session state to a shared cache and disable affinity.
Problem
Production runs on a single instance with no health check and no alerts.
Why It’s Harmful
Any restart or fault becomes downtime, and nobody finds out until customers complain.
Correct Approach
Run at least two instances, enable Health Check and alert on error rate and latency.
16Cost Optimization and Governance
The cloud bill is an architecture diagram written in money. Reading it well saves real budget.
How You Are Billed
In dedicated tiers you pay for each instance in each plan for the time it runs, whether or not it is busy. In an App Service Environment, you pay for each isolated worker, plus a baseline even when the environment is empty. With automatic scaling, instances are billed per second, including the prewarmed ones. Certificates, custom domains, outbound data transfer and supporting services such as a firewall, a gateway or a private endpoint add their own charges.
Paying for an App Service plan is like renting a taxi by the hour. It costs the same whether you carry one passenger or four. The way to save is to keep the taxi full of useful trips and send it back when nobody needs it.
Practical Ways to Spend Less
Right-size Plans
Review CPU and memory trends. If a plan idles at ten percent, move to a smaller size or fewer instances.
Consolidate Compatible Apps
Combine low-traffic apps of the same product into one plan, within the density rules we discussed earlier.
Schedule Scale-down
Use time-based rules to reduce capacity at night and weekends for internal tools.
Commit for Steady Load
For predictable workloads, reserved capacity or savings plans reduce the hourly rate in return for a time commitment. Availability of these options varies by plan generation, so check current terms.
Use Lower Tiers for Non-production
Development and test environments rarely need premium features. Dev and test pricing exists for some tiers on Windows and Linux.
Delete Orphans
Remove empty plans, unused slots, forgotten test apps and unattached certificates.
Governance Basics
Governance means making good behavior the default. Use Azure Policy to require HTTPS only, block public access where it should not exist, and enforce minimum TLS. Use tags to show owner, product and cost center on every plan so bills can be traced. Use role-based access control so only a few people can create expensive plans. Use budgets and alerts to catch runaway spend early.
Cost and performance are twins. A plan that is constantly overloaded is not cheap, because it costs you slow pages and lost customers. A plan that is empty is not safe, because it costs you waste. Aim for steady, moderate utilization with headroom for spikes.
17Real-World Examples and Choosing Alternatives
Patterns become clear when you see how different organizations shape the same service for different goals.
Industry Scenarios
Seasonal Retail Storefront
An online shop has quiet months and a huge holiday rush. It uses a Premium plan with automatic scaling to keep warm capacity ready, a distributed cache for carts, blob storage for product images, a global router with a firewall at the edge, and slots for safe releases during peak season when failure is most costly.
Bank Internal Portals
A financial institution hosts employee-facing tools in an internal App Service Environment inside its network. No internet exposure exists. Identity comes from the corporate directory, secrets from vaults, and all outbound traffic flows through a central firewall with full logging for auditors.
Software-as-a-Service Product
A growing software vendor runs a web front end, an API app and background workers in separate plans so each scales independently. Per-environment subscriptions, pipelines and managed identities keep staging and production firmly separated.
Healthcare Appointment System
A clinic network uses private endpoints for patient data stores, strict TLS settings, zone redundancy for availability, and detailed audit logs. Health checks and multiple instances keep appointment booking available around the clock.
Government Information Site
A public information site needs to survive election-night traffic. It uses a content delivery layer in front, generous maximum scale limits and a standby region behind a global router.
App Service Versus Other Compute Options
| Need | Best Fit | Why |
|---|---|---|
| Typical web app or API with simple operations | App Service | Fastest path to a secure, scalable, managed web workload |
| Short event-driven functions | Azure Functions | Pay per execution, trigger-based model |
| Containers with event-driven scale and microservices, less cluster work | Azure Container Apps | Container-native, scales based on events, including down to zero |
| Large container platforms with deep orchestration needs | Azure Kubernetes Service | Maximum control and flexibility, with maximum operational effort |
| Legacy software needing full operating system control | Virtual Machines | Full control for unusual requirements |
Picking Kubernetes because it is fashionable, then spending most of the budget keeping the cluster alive. Choose the simplest platform that satisfies your real requirements, and move up only when you hit a genuine limit.
Moving an Existing Application to App Service
Many teams arrive with an older application running on their own servers. A calm migration follows a pattern. First, assess the app: its framework version, its operating system dependencies, its use of local files, its need for scheduled jobs and its connections to internal systems. Second, fix the blockers, such as local file writes or hard-coded machine names, in the existing environment. Third, create the plan and a test app, connect the same dependencies and run realistic tests. Fourth, switch traffic gradually, using weighted routing or a slot, and keep the old system ready for a quick return. Finally, retire the old servers only after a full business cycle without problems.
Assess
List dependencies, configuration, file usage, background jobs and network needs.
Fix Blockers
Remove local state, replace machine-specific settings and update unsupported framework versions.
Build the Target
Create plans, slots, identities, networking and monitoring, ideally through repeatable infrastructure definitions.
Cut Over Gradually
Shift a small share of users first, watch the metrics and increase slowly.
Retire the Old Platform
Decommission only after stable operation, and capture lessons for the next migration.
Define your infrastructure as repeatable templates from the start. Environments that can be recreated from definitions are easier to review, easier to copy for testing and far easier to rebuild after a mistake.
18Best Practices and Common Mistakes
A compact checklist you can bring to design reviews.
Do These
- Run at least two instances for production workloads
- Deploy through a pipeline into a slot and swap
- Mark environment-specific settings as slot-specific
- Use managed identities and Key Vault references
- Enable Always On, Health Check and Application Insights
- Keep the web tier stateless and send uploads to blob storage
- Choose private endpoints and integration subnets for sensitive systems
- Tag every plan and set budgets and alerts
Avoid These
- Putting every app into one shared plan
- Relying on affinity cookies and in-memory sessions
- Leaving the direct public address open behind a firewall
- Hard-coding outbound IP addresses
- Storing secrets in source control or plain settings
- Running long jobs inside web requests
- Ignoring DNS when designing private access
- Treating the Free tier as production
A Maturity Ladder
Foundation
Standard or Premium plan, HTTPS only, two instances, pipeline deployments and basic alerts.
Hardened
Managed identity, Key Vault references, edge firewall, restricted management surface and central logs.
Private and Resilient
Private endpoints, integration subnets, zone redundancy, health checks and rehearsed recovery.
Global and Governed
Multi-region routing, policy-enforced standards, cost reviews and, where needed, an isolated environment.
19Frequently Asked Questions
Short, practical answers to questions that come up again and again.
You pay per plan instance in dedicated tiers. Adding more apps to an existing plan does not raise the bill by itself, but it can raise the load, which may force you to scale.
No. A plan is tied to one operating system, so you need separate plans for each.
The app was probably unloaded and is starting cold. Enable Always On on paid tiers, and consider prewarmed or always-ready instances with automatic scaling.
Autoscale follows rules and schedules that you write, using metrics like CPU. Automatic scaling follows incoming HTTP traffic on its own, supports always-ready and prewarmed instances and per-app limits, and needs a Premium tier. Use only one on a plan.
ARR Affinity may be pinning existing users to the busy instance. Disable affinity and make the app stateless so new instances can share the work.
Not necessarily. A private endpoint with public access disabled, combined with virtual network integration for outbound calls, gives strong privacy on Basic and higher tiers. Choose an environment when you need single-tenant isolation, environment-level network control or the highest scale.
Only the persistent content area survives restarts, and it is meant for deployed files. Put user data in a database or blob storage.
A properly warmed swap should not. The target slot starts, loads and responds before traffic is redirected. Poorly designed warm-up or non-sticky settings are the usual causes of trouble.
Integrate the app with a virtual network and send its outbound traffic through a NAT gateway or a firewall with a fixed public address.
A Standard-level plan or better with two instances, HTTPS only, a deployment slot, Application Insights and basic alerts. Beyond that, add features as the risk or scale of the workload demands.
Automatic scaling is disabled when web apps and function apps share a plan. Keep them in separate plans, or use a dedicated functions hosting option for functions.
No. Private endpoint traffic bypasses access restriction rules, so use network security controls on the subnet and keep private DNS correct.
20Summary and Key Takeaways
Azure App Service gives you a managed kitchen for your applications, but a professional chef still needs to understand the building. The plan is the real unit of compute and cost. Front ends and workers cooperate behind every request. Slots make releases calm. Identity replaces passwords. Scaling has three modes with different rules, and affinity can quietly undo all of them. Networking has separate inbound and outbound tools, and private designs rise or fall on DNS. An isolated environment is the right answer only when its isolation is truly needed. Above all, design every instance to be disposable, observe everything, and choose the simplest architecture that meets your real goals.
Key Takeaways
- The plan is what you pay for — apps share the plan’s machines, so plan density balances savings against noisy-neighbor risk.
- Stay stateless — keep sessions, files and data outside instances so scaling, restarts and failures are harmless.
- Release through slots — deploy to staging, warm up, swap, and roll back by swapping again, with sticky settings protecting each environment.
- Prefer identity over passwords — managed identities and Key Vault references remove secrets from code and configuration.
- Pick the right scaling mode — manual, rule-based autoscale and traffic-based automatic scaling differ, and ARR Affinity must be handled deliberately.
- Separate inbound from outbound — use access restrictions or private endpoints for inbound, integration subnets and NAT for outbound, and get private DNS right.
- Layer your defenses and your visibility — edge firewall, TLS, identity, locked management surface, central logs and meaningful alerts together protect production.