Rebalance your Resource Pools

VMware vSphere offers the ability to divide cluster resources into pools. There have been a lot of outstanding articles about resources. I want to emphasize especially the books written by Duncan Epping, Niels Hagoort and Frank Denneman.

Resource pools are a constant source of misconfiguration. Almost every cluster I see in the wild has some no-go’s configured. The most common reason is that RP are misunderstood as folders to organize VMs.

Do not use Resource Pools as folders

People keep thinking that if they leave all pools at “Normal” it wouldn’t be a problem. In fact it is a problem. Especially if the customer tried to organize his VMs into  hierarchical structures, resource pools can become very complicated to track and might do nasty things in times of contention.

If you need to organize your VMs, please do it in the “VM and Templates” view. You can build folder structures as you like and it will have no implications on resources.

Do not put sibling VMs on the same level as resource pools

This is also a very common mistake. All objects on the same hierarchical level of a resource will be treated as siblings. No matter if it’s just one VM or a pool of 100 VMs.

Imagine one resource pool “production” with 5 VMs in it and one sibling VM that is on the same level as the “Production” pool. Shares are all default (normal). In times of contention the pool will get 50% of the resource and the sibling VM will get another 50%. Leaving every VM inside the poll with just 10% of the clusters resource.

Be careful with default shares

Resource pools offer three default share settings. High, Normal and Low. They have a share ratio of 4:2:1 which sounds pretty good. Some customers put all their production VMs into a “High” pool and some Test&Dev VMs into a “Low” pool. Sounds logic and the customer expected to have four times as many resources for his production VMs than for his development VMs.

But having two VMs inside Test&Dev (low) and  80 VMs in “High” would have caused an unpleasant surprise if the  cluster had  faced a resource shortage. Leaving production VMs with 1% of the clusters resources, whereas  a Test&Dec VM would get 10% of resources under the same conditions. Luckily that never happened to the customer. 😉

This is called the resource pool paradox. Where a VM in a low priority pool can get more resources than a VM in high priority pool.  I can recommend one of the articles published on Yellow-Bricks about this topic.

How to size pools properly

Using default pools isn’t enough. You must regard how many resources (vCPU or MB) are consumed within the pool and assign custom shares accordingly.

Shares are not an absolute value. It’s a ratio i.e. 4:2:1 is the same as 4000:2000:1000 or 84:42:21. But keep in mind that the maximum value for a share is 4000000.


I will show the example for CPU shares, but memory shares are calculated accordingly.

Imagine you have three pools and you want to priorize them in a ratio of 4:2:1. Sup up the vCPU of all VMs in each pool.

Pool vCPU shares per vCPU total shares % of parent pool Resources p. vCPU
Critical 28 40 1120 33% 1,2%
Production 108 20 2160 64% 0,6%
Test 12 10 120 3% 0,3%

As you can see, the “Critical” pool does not get more shares than the production pool, even though it has double weight compared to “Production”. The point is that there are far less vCPU inside the critical pool. So the whole pool will get one third (33%) of the clusters resources, whereas the production pool gets 64% and the Test pool only gets 3%.

That doesn’t look like 4:2:1 but in fact it is 4:2:1 if you’re looking on how much cluster resources each vCPU in the pool will get. You can see that from a vCPU point of view it is a perfect 4:2:1 ratio.

Do the math or use a script

The downside of that method is that you have to recalculate shares every time something changes. Either VMs change pools, new VMs are created, old ones get deleted, or VM hardware changes (more/less vCPU or RAM). This can be quite time consuming. That’s why I wrote a powerCLI script to do the job (I’m a lazy person).

What it does

The script is based on code originally published by Chris Wahl. He used the number of VMs as a calculation base.  That’s a good approximation, but I wanted a calculation based on the resources vCPU and memory. So I modified the script and changed the calculation.

You can either invoke the script with two parameters (vcenter, cluster), or edit the scripts default values to match your environment.

After you enter your credentials for vCenter it will check every RP in the cluster and count its VMs, total vCPU and memory. Then you’ll be asked how many shares a vCPU should get. Then how many shares a GB of memory should get.

Then the share values are set to that pool and the script moves on to the next RP.

The script

Please remind that this script has no brain – use your own! And don’t blame me if a kitten gets hurt or a meltdown occurs in your datacenter. I do apologize for bad coding.

Download the Code RPCalculator or copy from below.

# invoke script with parameters -vcenter <vc FQDN> and -cluster <clustername>

# This script is based on code originally published by Chris Wahl
# Modified and extended by Michael Schroeder
# published on

# edit default values here
[string]$vcenter = "",
[string]$cluster = "myCluster"
# --------------
# stop editing

## Variables
[int]$vCPU = 0
[int]$vMem = 0
[int]$vMemGB = 0
[int]$percpushares = 0
[int]$permemshares = 0
[int]$rpsharesC = 0
[int]$rpsharesM = 0

## get resource pools
Connect-VIServer $vcenter
[array]$rpools = Get-ResourcePool -Location (Get-Cluster $cluster)


Foreach ($rpool in $rpools)
	If ($ -ne "Resources")

		$vCPU = Get-VM -Location $rpool | Measure-Object -Property NumCpu -Sum | select -ExpandProperty Sum
		$vMem = Get-VM -Location $rpool | Measure-Object -Property MemoryMB -Sum | select -ExpandProperty Sum
		$vMemGB = [System.Math]::Round($vMem / 1024)
		$totalvms = $rpool.ExtensionData.Vm.count
		Write-Host -ForegroundColor Green -BackgroundColor Black " Pool " $
		Write-Host -ForegroundColor Green -BackgroundColor Black "-----------------------------"
		Write-Host "Total VMs in pool " -nonewline
		Write-Host -ForegroundColor Green -BackgroundColor Black $($rpool.Name) -nonewline
		Write-Host " : " -nonewline
		Write-Host -ForegroundColor White -BackgroundColor Black $totalvms
		Write-Host "Total memory in pool " -nonewline
		Write-Host -ForegroundColor Green -BackgroundColor Black $($rpool.Name) -nonewline
		Write-Host " : " -nonewline
		Write-Host -ForegroundColor White -BackgroundColor Black $vMemGB "GB"
		Write-Host "Total vCPU in pool " -nonewline
		Write-Host -ForegroundColor Green -BackgroundColor Black $($rpool.Name) -nonewline
		Write-Host " : " -nonewline
		Write-Host -ForegroundColor White -BackgroundColor Black $vCPU
		$percpushares = Read-Host "How many shares per vCPU in the $($rpool.Name) resource pool? "
		$permemshares = Read-Host "How many shares per GB in the $($rpool.Name) resource pool? "

		$rpsharesC = $percpushares * $vCPU
		$rpsharesM = $permemshares * $vMemGB 
		# maximum value for share is 4000000
		if ($rpsharesC -lt 4000000 -and $rpsharesM -lt 4000000)
			Write-Host "CPU Shares will be set to $vCPU * $percpushares = " -nonewline
			Write-Host -ForegroundColor Black -BackgroundColor Yellow $rpsharesC
			Write-Host "Memory Shares will be set to $vMemGB * $permemshares = " -nonewline
			Write-Host -ForegroundColor Black -BackgroundColor Yellow $rpsharesM
			# write values to resourcepool
			Set-ResourcePool -ResourcePool $rpool.Name -CpuSharesLevel:Custom -NumCpuShares $rpsharesC -MemSharesLevel:Custom -NumMemShares $rpsharesM -Confirm:$true | Out-Null
			Write-Host -ForegroundColor Red -BackgroundColor Black "Value too high"
			Write-Host "Maximum share value is 4000000"
			Write-Host "CPU Shares value: " -nonewline
			Write-Host -ForegroundColor Red -BackgroundColor Black $rpsharesC
			Write-Host "Memory Shares value: " -nonewline
			Write-Host -ForegroundColor Red -BackgroundColor Black $rpsharesM




Leave a Reply

Your email address will not be published.