Autoscaling VM Scale Sets in Azure

Autoscaling lets a VM Scale Set grow and shrink in response to load automatically, without manual intervention. Azure’s autoscale engine monitors metrics — CPU utilisation, queue length, or custom signals — and adds or removes instances to keep your application performing well without paying for idle capacity. This page walks through configuring both metric-based and schedule-based autoscale rules.

Autoscale building blocks

Azure autoscale for Scale Sets is built from three components:

  • Profiles. A profile groups a set of capacity limits and scaling rules. Most configurations have a default profile, and optionally a recurrence profile for scheduled periods (like weekday business hours).
  • Capacity settings. Each profile defines minimum, maximum, and default instance counts. Autoscale will never scale below the minimum or above the maximum.
  • Rules. Each rule defines a metric condition and an action. When the metric crosses the threshold, the Scale Set adds or removes a fixed number of instances (or a percentage).

Scale-out rules (add instances) and scale-in rules (remove instances) are defined separately and should be asymmetric. Scale out aggressively to handle load spikes quickly. Scale in conservatively to avoid flapping — repeatedly adding and removing instances as load fluctuates around the threshold.

Configuring CPU-based autoscaling

The most common autoscale configuration scales out when average CPU exceeds 70% and scales in when it drops below 30%. The cooldown period prevents rapid oscillation.

# Attach autoscale settings to a Scale Set
az monitor autoscale create \
  --resource-group my-rg \
  --resource my-scale-set \
  --resource-type Microsoft.Compute/virtualMachineScaleSets \
  --name my-autoscale-settings \
  --min-count 2 \
  --max-count 10 \
  --count 2

# Scale out: add 2 instances when avg CPU > 70% for 5 minutes
az monitor autoscale rule create \
  --resource-group my-rg \
  --autoscale-name my-autoscale-settings \
  --condition "Percentage CPU > 70 avg 5m" \
  --scale out 2 \
  --cooldown 5

# Scale in: remove 1 instance when avg CPU < 30% for 10 minutes
az monitor autoscale rule create \
  --resource-group my-rg \
  --autoscale-name my-autoscale-settings \
  --condition "Percentage CPU < 30 avg 10m" \
  --scale in 1 \
  --cooldown 10

A few things to note in this configuration:

  • The minimum instance count is 2. Autoscale will never go below 2 instances, ensuring no single point of failure.
  • Scale-out uses a 5-minute evaluation window and 5-minute cooldown. Scale-in uses a 10-minute window and 10-minute cooldown. This asymmetry prevents scale-in decisions based on a brief CPU drop.
  • Scale out adds 2 instances at once rather than 1. Adding in batches helps recover from a surge more quickly.

Schedule-based autoscaling

If your application has predictable traffic patterns — for example, high traffic during business hours and low traffic overnight — add a scheduled profile to pre-warm instances before the peak:

# Scale up to 5 instances at 7am UTC on weekdays
az monitor autoscale profile create \
  --resource-group my-rg \
  --autoscale-name my-autoscale-settings \
  --name weekday-peak \
  --min-count 5 \
  --max-count 15 \
  --count 5 \
  --recurrence week mon tue wed thu fri \
  --timezone "UTC" \
  --start 07:00 \
  --end 20:00

During the scheduled profile window (7am to 8pm UTC weekdays), the minimum instance count is 5 and the maximum is 15. Outside the window, the default profile takes over with its minimum of 2. Metric-based rules still apply within the scheduled window — if CPU spikes above 70%, Azure still adds instances up to the profile maximum of 15.

Scaling on custom metrics

CPU is a convenient proxy but not always the right signal for scaling. A message-processing application should scale based on queue depth, not CPU — a slow message deserialisation step might show 100% CPU per instance but still process messages slowly, while an I/O-bound fetching operation uses 5% CPU but has thousands of messages waiting.

Azure autoscale supports scaling on any metric in Azure Monitor, including:

  • Storage Queue message count — scale out when queue depth exceeds a threshold
  • Service Bus queue active message count — common for worker process Scale Sets
  • Application Insights custom metrics — any metric your application emits
  • HTTP request queue length from Application Gateway or Load Balancer

Custom metric scaling requires specifying the metric namespace and metric name in the autoscale rule. Consult the Azure Monitor metrics reference for the exact namespace and name for the service you want to scale on.

Scale-in policy: which instances are removed

When autoscale decides to scale in, it needs to choose which instances to remove. Azure offers three policies:

  • Default. Azure removes instances with the highest instance ID first, balancing across Availability Zones. Good for most cases.
  • OldestVM. The oldest instance is removed first. Useful when you want to cycle instances regularly to keep OS patches current.
  • NewestVM. The newest instance is removed first. Useful when scaling back after a spike — removes the most recently added capacity without disrupting instances that have been running longer and may have warmed up caches.

For Scale Sets mixing regular and Spot instances, the scale-in policy also determines whether Spot or regular instances are removed first when scaling in — an important consideration for cost management.

Diagnosing autoscale behaviour

When autoscale does not behave as expected, check the autoscale history:

# View autoscale history for the last hour
az monitor autoscale history list \
  --resource-group my-rg \
  --autoscale-name my-autoscale-settings \
  --output table

Each history entry shows the time, the rule that triggered, the action taken, and whether it succeeded. Common reasons for unexpected behaviour:

  • Cooldown period still active — Azure will not scale again until the cooldown expires
  • Already at minimum or maximum count — no further scaling is possible
  • Conflicting rules — a scale-out and scale-in rule both matching simultaneously causes the scale-out rule to win
  • Metric data lag — Azure Monitor metrics have a 1–5 minute ingestion delay; rules using very short evaluation windows may miss spikes

Common autoscaling mistakes

  1. Setting identical scale-out and scale-in thresholds. If scale-out triggers at 60% CPU and scale-in triggers at 60% CPU, adding instances reduces per-instance CPU slightly, which immediately triggers scale-in, which raises CPU, which triggers scale-out — an endless flapping loop. Keep a gap between the two thresholds (for example, scale out at 70%, scale in at 30%).
  2. Not accounting for cold-start time. If your VM bootstrap takes 8 minutes, autoscale will not help you absorb a traffic spike that peaks in 5 minutes. Pre-warm with scheduled scaling, or switch to a faster-booting container-based solution for latency-sensitive scale requirements.
  3. No minimum instance count. A minimum of 0 saves money during quiet periods but means your first user after an idle period waits for a fresh VM to boot. Decide whether cold starts are acceptable for your workload before setting minimum to 0.

Frequently asked questions

How long does it take for new Scale Set instances to come online?

It depends on how fast your VM boots. A VM booting from a Marketplace image with a bootstrap script can take 5–15 minutes. A VM booting from a pre-baked custom image can be ready in 1–3 minutes. For workloads with fast spikes, pre-warm your instances by keeping a minimum count above zero and using scale-out aggressively, or consider Azure Container Apps which scales to zero and back much faster.

What is the difference between metric-based and schedule-based autoscaling?

Metric-based autoscaling reacts to live data — CPU, memory, queue depth, or custom metrics — and scales when thresholds are crossed. Schedule-based autoscaling adjusts capacity on a time table regardless of current load. Many production systems use both: a schedule to pre-warm before known peak periods, and metrics to handle unexpected surges.

Can autoscaling scale to zero?

Scale Sets have a minimum instance count setting. You can set it to zero, which means the Scale Set will scale down completely when there is no load. However, cold-start time (booting from zero to the first instance handling traffic) can be 2–10 minutes depending on image size and bootstrap time. For workloads that need to respond instantly, keep a minimum of 1 or 2 warm instances.

Last verified: 19 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.