# Power Management Auto Scaling in AVD

Click [here](https://github.com/MicrosoftLearning/AZ-140-Configuring-and-Operating-Microsoft-Azure-Virtual-Desktop/blob/master/Instructions/Labs_EntraID/05_LAB_41_02_Implement_autoscaling_of_session_hosts.md) for the github version of Microsoft ESI lab.

Configure autoscaling for an Azure Virtual Desktop environment to optimize resource utilization by dynamically scaling session hosts based on demand.

**Note:** To enable autoscale for Azure Virtual Desktop, you must grant the service principal permissions to manage the power state of session host VMs. This is done using the built-in **Desktop Virtualization Power On Off Contributor** RBAC role.

Ensure that this role is assigned at the **subscription scope**—assigning it at a lower level (e.g., resource group, host pool, or VM) will prevent autoscale from functioning correctly.

This role differs from **Desktop Virtualization Power On Contributor**, which is used in the *Manage host pools and session hosts* lab to support *Start VM on Connect* functionality.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1739817911168/61786d84-bcc6-48ac-9b1b-07bedbd0abe5.png align="center")

There are two scaling methods, but now let's focus on **Power Management Autoscaling**:

### **Power Management Autoscaling**

* VMs are only turned on or off to adjust capacity.
    
* This is the only option if your host pools **do not** use session host configuration.
    

### **Dynamic Autoscaling (Preview)**

* Manages capacity by both **turning on/off existing VMs** and **creating/deleting VMs** as needed.
    

### Evaluating Azure Virtual Desktop Autoscale Functionality

#### Case Overview

The evaluation of the Azure Virtual Desktop (AVD) autoscaling functionality was performed by configuring a host pool with predefined scaling settings. The goal was to observe how the system dynamically adjusted session hosts based on user demand and predefined parameters.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1739818873598/f69482d0-b97b-40a4-990e-5e7488205dfe.png align="center")

#### Initial Setup

The host pool (az140-21-hp1) was configured with three session hosts. The following settings were established to facilitate testing:

**Max session limit**: Set to 1 to illustrate autoscaling behavior(HP Setting\\Properties).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1739819199423/b788201f-dcb3-432c-9bf3-17266c0449ee.png align="center")

**Note**: The schedule effectively covers every day of the week, which will facilitate evaluating outcome of autoscaling.

* **Scaling plan**: Created with ramp-up, peak, ramp-down, and off-peak hours for week days and specified autoscaling triggers. Scaling plan must include an associated schedule for at least one day of the week..
    
* Ramp-up Start time here: <mark>one hour less than our current local time</mark>
    
* ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1739819747860/04c9f999-e33d-481f-8d4d-ead682cd0b41.png align="center")
    

**Note:** The *Minimum percentage of hosts* setting determines the lowest percentage of session hosts to maintain as running during ramp-up and peak hours. For example:

* If the minimum is set to **30%** and your host pool contains **3 session hosts**, Autoscale will ensure at least **1 host** (30% of 3, rounded up to the nearest whole number) remains active and available to handle user connections.
    

**Note:** For pooled host pools, autoscale overrides any existing load-balancing algorithms configured in your host pool settings. Instead, it applies load balancing based on the schedule configuration you define.

* **Capacity thresholds**:
    
    * Ramp-up and peak hours: 60%
        
    * Ramp-down and off-peak hours: 80%
        
* **Minimum active hosts**:
    
    * Ramp-up: 30% of total session hosts (rounded up to 1 host).
        
    * Ramp-down: 10% of total session hosts (rounded up to 1 host).
        
* **Note:** The *Capacity Threshold* setting defines the percentage of used host pool capacity that triggers Autoscale to evaluate whether additional session hosts should be turned on or off during ramp-up and peak hours.
    
    For example:
    
    * If the capacity threshold is set to **60%** and your host pool has a capacity of **1 session** (with one host running), Autoscale will activate additional session hosts once the host pool’s load (load= user actively using the session) exceeds **60%** (which, in this case, is equivalent to 100% utilization).
        

Peak hours start time here is: <mark>Current time + 1 hours</mark>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1739830624248/0168c781-7cec-4936-a5fe-decafd086507.png align="center")

**Note**: The **Capacity threshold (%)** setting is shared between the **Ramp-up** and **Peak hours** settings.

**Ramp Down:**

* <mark>Ramp-down</mark> start time here is: <mark>Current time + 2 hours</mark>
    
* **Note:** The *Minimum Percentage of Active Hosts (%)* setting specifies the lowest percentage of session host virtual machines to maintain during ramp-down and off-peak hours.
    
    For example:
    
    * If the minimum percentage is set to **10%** and your host pool contains **3 session hosts**, Autoscale will ensure at least **1 session host** (10% of 3, rounded up) remains active to handle user connections.
        

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1739820296864/11e2eac2-1234-49d2-b6ec-d2b02aacf3c1.png align="center")

**Note:** The *Capacity Threshold (%)* setting defines the percentage of used host pool capacity that Autoscale uses to determine when to turn off virtual machines during ramp-down and off-peak hours.

For example:

* With **1 user connection** and **3 hosts running**, if the capacity threshold is set to **80%**, Autoscale will turn off **1 host**, reducing the used capacity to **50%**.
    

<mark>Off-peak hours</mark> start time here is: <mark>Current time + 3 hours</mark>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1739820328935/4770894c-a530-4d0c-a9e1-dc28166d0455.png align="center")

**Note:** Autoscale stops and deallocates session hosts based on the following rules:

1. The used host pool capacity is below the defined **Capacity Threshold**.
    
2. Turning off session hosts will not cause the used capacity to exceed the **Capacity Threshold**.
    
3. Autoscale only deallocates session hosts with no user sessions, unless:
    
    * The scaling plan is in the **ramp-down phase**, and
        
    * The setting to **force user logoff** is enabled.
        
4. During the **ramp-up phase**, pooled Autoscale will not turn off session hosts to ensure user experience remains unaffected.
    

**Note**: The **Capacity threshold** setting is shared between the **Ramp-down** and **Off-peak hours** settings.

---

## Autoscaling Evaluation

1. **Evaluate the Ramp-up Settings:**
    
    * Review the **Power state** of the session hosts and verify that one host is listed as **Running**.
        
        * **Note:** It may take a few minutes for the first session host to reach the **Running** state.
            
        * **Note:** This behavior is expected. Based on the **Ramp-up settings** of the newly created scaling plan, at least **one session host** must remain online at all times.
            

> Currently:
> 
> * The host pool capacity is **1** (with only 1 host running).
>     
> * The used host pool capacity is **0%**, as there are no active user connections.
>     

2. **Evaluate the Ramp-up and Peak Hours Capacity Threshold:**
    
    * Start using a session (full desktop or remote app)
        

**Note:** At this point, the used host pool capacity is now **100%**, exceeding the **60% capacity threshold**. Autoscale will activate another host, reducing the used capacity to **50%**. Since this is below the threshold, the third host will remain **stopped/deallocated**. You will verify this behavior in the next steps.

3. **Verify Autoscaling Behavior:**
    
    * On the **host pool | session hosts** page, select **Refresh**.
        
    * Verify that **two session hosts** are now listed as **Running**.
        
4. **Evaluate the Ramp-down Capacity Threshold:**
    
    * In the **week\_schedule** pane navigate to the **Ramp-down** tab and adjust the **Start time** to a time between the **Peak hours Start time** and the current time.
        
        * **Note:** You may need to adjust the **Peak hours Start time** as well.
            
5. **Log Off and Verify Ramp-down Behavior:**
    
    * Switch to the **Command Prompt** window and enter the following command: **logoff**
        
    * Return to the Azure portal and navigate back to **az140-21-hp1 | Session hosts**.
        
    * Verify that only **one session host** remains **Running**.
        
        * **Note:** It may take 1-2 minutes for the session host to shut down.
            

---

### **Example Scenario**

* **Minimum Percentage of Hosts**:
    
    * **Ramp-Up**: 20% of hosts must remain active.
        
    * **Ramp-Down**: 10% of hosts must remain active.
        
* **Load Balancing Algorithm**:
    
    * **Ramp-Up**: Breadth-first (sessions distributed evenly across hosts).
        
    * **Ramp-Down, Peak Hours, and Off-Peak Hours**: Depth-first (sessions assigned to the first available host until it reaches capacity).
        

With **2 hosts** and each host supporting up to **4 sessions**, here’s the table and explanation:

---

### **Updated Table**

| **Phase** | **Active Hosts** | **Capacity Threshold** | **Sessions per Host** | **Load Balancing** | **Description** |
| --- | --- | --- | --- | --- | --- |
| **Ramp-Up** | Active hosts **≥** 20% | Host capacity **&lt;** 60% | ≤ 2 sessions per host | Breadth-first | Hosts are activated, and sessions are distributed evenly across hosts. |
| **Peak Hours** | Active hosts **\=** 100% | Host capacity **≤** 60% | ≤ 2 sessions per host | Depth-first | Both hosts are active, and sessions are assigned to the first available host. |
| **Ramp-Down** | Active hosts **≥** 10% | Host capacity **&lt;** 90% | ≤ 3 sessions per host | Depth-first | Hosts are deactivated gradually, and sessions are assigned to the first host. |
| **Off-Peak Hours** | Active hosts **≥** 10% | Host capacity **&lt;** 90% | ≤ 3 sessions per host | Depth-first | Only the minimum required host is active, handling sessions depth-first. |

---

### **Key Adjustments**

1. **Minimum Percentage of Hosts**:
    
    * **Ramp-Up**: 20% of 2 hosts = **1 host** must remain active.
        
    * **Ramp-Down**: 10% of 2 hosts = **1 host** must remain active.
        
2. **Load Balancing Algorithm**:
    
    * **Ramp-Up**: **Breadth-first** ensures sessions are distributed evenly across hosts.
        
    * **Ramp-Down, Peak Hours, and Off-Peak Hours**: **Depth-first** assigns sessions to the first available host until it reaches capacity.
        
3. **Capacity Threshold**:
    
    * **Ramp-Up and Peak Hours**: 60% capacity = **2 sessions per host**.
        
    * **Ramp-Down and Off-Peak Hours**: 90% capacity = **3 sessions per host**.
        

---

### **Example Scenario**

Let’s walk through a typical day with **2 hosts** and **up to 4 sessions per host**:

#### **Ramp-Up (Morning)**

* **Active Hosts**: 1 host (20% of 2 hosts).
    
* **Sessions per Host**: Up to 2 sessions per host (60% capacity).
    
* **Load Balancing**: Breadth-first (sessions distributed evenly).
    
* **What Happens**:
    
    * If there are 2 sessions, both are assigned to the first host.
        
    * If there are 3 sessions(%75 &gt; %60), the first host gets 2 sessions, and the second host gets 1 session.
        

#### **Peak Hours (Midday)**

* **Active Hosts**: 2 hosts (100% of hosts).
    
* **Sessions per Host**: Up to 2 sessions per host (60% capacity).
    
* **Load Balancing**: Depth-first (sessions assigned to the first available host).
    
* **What Happens**:
    
    * New sessions are assigned to the first host until it reaches 2 sessions.
        
    * Once the first host is full, new sessions are assigned to the second host.
        

#### **Ramp-Down (Evening)**

* **Active Hosts**: 1 host (10% of 2 hosts).
    
* **Sessions per Host**: Up to 3 sessions per host (90% capacity).
    
* **Load Balancing**: Depth-first (sessions assigned to the first available host).
    
* **What Happens**:
    
    * The remaining host handles up to 3 sessions.
        
    * If there are 4 sessions, the first 3 are assigned to the active host, and the 4th session may wait or trigger activation of the second host temporarily.
        

#### **Off-Peak Hours (Night)**

* **Active Hosts**: 1 host (10% of 2 hosts).
    
* **Sessions per Host**: Up to 3 sessions per host (90% capacity).
    
* **Load Balancing**: Depth-first (sessions assigned to the first available host).
    
* **What Happens**:
    
    * The active host handles up to 3 sessions.
        
    * If there are more than 3 sessions, the system may temporarily activate the second host.
        

---

### **Why This Configuration Works**

* **Ramp-Up (Breadth-first)**:
    
    * Ensures sessions are distributed evenly across hosts, preventing overloading a single host.
        
* **Peak Hours, Ramp-Down, and Off-Peak Hours (Depth-first)**:
    
    * Optimizes resource utilization by filling one host at a time before moving to the next.
        
* **Minimum Percentage of Hosts**:
    
    * Ensures at least one host is always active to handle sessions, even during low-demand periods.
        

---

### **Summary**

With **2 hosts** and **up to 4 sessions per host**, the system dynamically scales resources based on demand:

* **Ramp-Up**: 1 host active, sessions distributed evenly (breadth-first), up to 2 sessions per host (60% capacity).
    
* **Peak Hours**: 2 hosts active, sessions assigned depth-first, up to 2 sessions per host (60% capacity).
    
* **Ramp-Down**: 1 host active, sessions assigned depth-first, up to 3 sessions per host (90% capacity).
    
* **Off-Peak Hours**: 1 host active, sessions assigned depth-first, up to 3 sessions per host (90% capacity).
