Preempted Batch node stays in the pool, misleads Batch autoscaling

JeffreyCMI 116 Reputation points
2026-07-22T18:48:08.12+00:00

I run Azure Batch pools using spot nodes. Occasionally a node is preempted, which itself is not a problem. But I struggle to wrap my head around what happens to that node after it's preempted.

I observe is that the preempted node remains in the pool, and I have three questions about this:

  1. What happens to a Batch pool node after it gets preempted, and when? Do they ever leave the pool? Do they ever try to "recover" out of their Preempted state to Running again? I have not observed either of these; it seems that they just remain Preempted forever.
  2. Am I being billed for the preempted node as long as it remains part of the Batch pool?
  3. Autoscaling does not discount this preempted node when it checks if it has enough nodes or if it needs to scale-out. In my case, my Job had 1 active Task, the autoscaling rule therefore correctly set $TargetLowPriorityNodes -1But no new nodes were added because there was already 1 node in the pool; it didn't account for the fact that it was preempted so nothing could run on it. Assuming preempted nodes remain in that state indefinitely, is there a workaround to tell the scaling not to count them?

Here's max Preempted node count over the span of 2 days. On Tue 21, the count rose from 0 -> 1, when a very large pool had just 1 (or 2?) nodes preempted. But then that preempted node remains forever, until I manually deleted it. I can't explain the intermittent observations of count=2, but I wasn't actively watching the pool at those times.

User's image

Azure Batch
Azure Batch

An Azure service that provides cloud-scale job scheduling and compute management.


3 answers

Sort by: Most helpful
  1. JeffreyCMI 116 Reputation points
    2026-07-29T14:00:46.8033333+00:00

    As an observer watching my Batch pools, I was able to confirm the following behaviors, all of which address my questions. I posted this as a new comment because my empirical observations have a lot of overlap with, but also slight differences from, the other comments posted here.

    What happens to a batch node after it gets preempted?

    In this case, my observations completely match VarunTha's response. Batch will periodically attempt to re-provision them (this is where I believe Alex Burlachenko is mistaken). The entire time -- even in Preempted state -- the node counts toward the pool size.

    The only thing that would remove a Preempted node from the pool is an autoscaling rule doing general scale-in.

    Am I being billed for the preempted node?

    The VM is gone, so you are not billed for compute. But I observe the hard disk and networking for the node remain while the node is preempted, so you do get billed for those. This is typically a tiny fraction of what the compute cost would have been: In my experience we pay about $1/day/preempted-node (USD).

    Autoscaling does not discount this preempted node when it checks if it has enough nodes.

    This statement is correct. And it's consistent with the observation that Batch is trying to re-provision the preempted node, so from the autoscaler's point of view, that preempted node might yet do some more work!

    One workaround to prevent starvation (when the preempted nodes never recover) may be to over-provision the pool. For example I use this:

    lookbackMinutes = 3;
    
    // Nodes preempted in the pool count toward pool size but run nothing,
    // so we add additional capacity to avoid task starvation.
    $preemptedNodes = max($PreemptedNodeCount.GetSample(TimeInterval_Minute * lookbackMinutes));
    $TargetLowPriorityNodes = $targetNodes + $preemptedNodes;
    

    I can't really explain the supply-and-demand of why this works. i.e. How can the autoscaler provision new nodes when existing nodes remained preempted? Oh well, no problem.

    Was this answer helpful?

    1 person found this answer helpful.

  2. VarunTha 15,085 Reputation points Microsoft External Staff Moderator
    2026-07-29T14:48:45.8766667+00:00

    Hello JeffreyCMI,

    Thank you for the clarification. You are correct that the re-provisioning attempt for the preempted Spot node is separate from the Batch autoscale evaluation.

    From the Compute side, after the Spot VM is preempted, the underlying VM is deleted, so VM compute charges stop. However, associated resources such as managed disks, public IP addresses, and load-balancer rules may continue to incur charges while they remain allocated.

    Azure Batch keeps the node record in the Preempted state and may attempt to restore the Spot capacity for up to 48 hours. The preempted node can therefore continue to count towards the pool target, even though it cannot run tasks.

    Your use of $PreemptedNodeCount to add replacement capacity is a reasonable workaround for avoiding task starvation. The exact interaction between the Batch autoscale calculation and the retained preempted node is owned by the Azure Batch service rather than the Compute platform.

    Thank you for sharing the detailed observations and billing breakdown. This distinction will also help other customers using Spot nodes with Batch autoscaling.

    Was this answer helpful?

    0 comments No comments

  3. Alex Burlachenko 25,030 Reputation points MVP Volunteer Moderator
    2026-07-23T09:04:34.96+00:00

    hi JeffreyCMI & thx for sharing urs issue here at Q&A portal,

    What u're seeing is generally expected for Spot nodes. When a Spot VM is preempted, the Batch node transitions to the Preempted state and the tasks running on it are terminated. The node doesn't immediately become usable again, and it won't automatically recover to Running. Whether it's eventually removed or replaced depends on the pool configuration and autoscale evaluation. (learn.microsoft.com) u aren't billed for compute while the underlying Spot VM has been evicted, but the presence of the Batch node object in the pool is separate from compute billing. The node record can remain even though there is no active VM behind it.

    The autoscale behavior is the part that stands out. A permanently Preempted node continuing to satisfy $TargetLowPriorityNodes so that no replacement node is allocated isn't what I'd expect. Normally the pool should converge back to the target number of usable Spot nodes. As a workaround, many customers periodically remove nodes that remain in the Preempted state so the autoscaler can provision replacements. If the node stays preempted indefinitely and continues to count toward the target, I'd treat that as a potential Batch service issue rather than expected behavior.

    I'd recommend opening a Batch support case with the pool ID, account name, region, autoscale formula, and timestamps where the node remained Preempted while $TargetLowPriorityNodes was still 1 and no replacement was allocated. The Batch team can verify from backend telemetry whether the autoscaler is incorrectly counting preempted nodes toward the target or whether the pool has become stuck.

    rgds,

    Alex

    &

    If my answer was helpful pls mark it and additional thx if u follow me at Q&A portal

    and at my blog https://ctrlaltdel.blog/

     

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.