@@ -132,7 +132,18 @@ func (a *AutoScaler) Scale(ctx context.Context, scaler *scalerv1alpha1.BudAIScal
132132
133133 // Build scaling request
134134 readyPodCount := a .countReadyPods (pods )
135- startingPodCount := a .countStartingPods (pods )
135+ runningNotReadyCount := a .countStartingPods (pods )
136+
137+ // Count pending pods - these are also "starting" as they represent
138+ // capacity that's been requested but not yet available
139+ pendingPodCount , err := a .countPendingPods (ctx , scaler , scale )
140+ if err != nil {
141+ klog .V (4 ).InfoS ("Failed to count pending pods" , "scaler" , scaler .Name , "error" , err )
142+ pendingPodCount = 0
143+ }
144+
145+ // Total starting pods = running-but-not-ready + pending
146+ startingPodCount := runningNotReadyCount + pendingPodCount
136147
137148 request := algorithm.ScalingRequest {
138149 Scaler : scaler ,
@@ -145,7 +156,8 @@ func (a *AutoScaler) Scale(ctx context.Context, scaler *scalerv1alpha1.BudAIScal
145156 }
146157
147158 klog .V (4 ).InfoS ("Pod counts" , "scaler" , scaler .Name ,
148- "readyPods" , readyPodCount , "startingPods" , startingPodCount ,
159+ "readyPods" , readyPodCount , "runningNotReady" , runningNotReadyCount ,
160+ "pendingPods" , pendingPodCount , "totalStarting" , startingPodCount ,
149161 "totalRunning" , len (pods ), "desiredReplicas" , scale .Spec .Replicas )
150162
151163 // Get last scale time from status
@@ -279,6 +291,35 @@ func (a *AutoScaler) countStartingPods(pods []corev1.Pod) int32 {
279291 return count
280292}
281293
294+ // countPendingPods counts pods that are in Pending state.
295+ // These are pods that have been requested but not yet scheduled or started.
296+ // They represent capacity that's been committed but not yet available.
297+ func (a * AutoScaler ) countPendingPods (ctx context.Context , scaler * scalerv1alpha1.BudAIScaler , scale * Scale ) (int32 , error ) {
298+ // Parse selector from scale
299+ selector , err := labels .Parse (scale .Status .Selector )
300+ if err != nil {
301+ return 0 , fmt .Errorf ("failed to parse selector: %w" , err )
302+ }
303+
304+ // List all pods matching selector
305+ podList := & corev1.PodList {}
306+ err = a .client .List (ctx , podList , & client.ListOptions {
307+ Namespace : scaler .Namespace ,
308+ LabelSelector : selector ,
309+ })
310+ if err != nil {
311+ return 0 , fmt .Errorf ("failed to list pods: %w" , err )
312+ }
313+
314+ var count int32
315+ for _ , pod := range podList .Items {
316+ if pod .Status .Phase == corev1 .PodPending && pod .DeletionTimestamp == nil {
317+ count ++
318+ }
319+ }
320+ return count , nil
321+ }
322+
282323// isPodReady checks if a pod is ready.
283324func isPodReady (pod * corev1.Pod ) bool {
284325 for _ , condition := range pod .Status .Conditions {
0 commit comments