Workload Autoscaler Reference
Use this reference to interpret saved Workload Autoscaler (WA) settings before recommending a change. A RecommendationPolicy calculates resource targets; an AutoscalingPolicy selects workloads and controls application; the generated, namespaced AutoscalingPolicyConfiguration (APC) records the effective configuration and observed state for one workload.
Scope, paths, and availability
This page describes the configuration supported by the current management and WA source contracts. It is not a promise that every cluster already runs the matching release. Check get_workload_autoscaler_configuration → data.configuration.workloadAutoscalerVersion, the installed CRDs, and the installed controller/webhook before using an optional field. A management-server or Console update alone does not upgrade the cluster controller.
Settings are provider-neutral unless noted; Kubernetes support, agent/controller versions, metrics availability, and runtime detection still constrain behavior on EKS, AKS, GKE, and ACK. In-place updates and Startup Boost require the cluster prerequisites in the InPlace guide, including Kubernetes 1.33+.
MCP paths below refer to structured tool output, not the human-readable summary:
| Object | Read tool and response root | Canonical configuration path |
|---|---|---|
| Cluster settings | get_workload_autoscaler_configuration → data.configuration | Management configuration, not a policy CRD |
| RecommendationPolicy | get_recommendation_policy → data.spec | RecommendationPolicy.spec |
| AutoscalingPolicy | get_autoscaling_policy → data.spec; enabled state at data.enable | AutoscalingPolicy.spec; enable is management state, not a CRD spec field |
| Workload | get_workload_detail → data | Effective projection; not the complete APC resource |
| Runtime history | get_workload_runtime_metrics → data.series[] | Collected JVM or pressure samples, not editable settings |
Use list_recommendation_policies, list_autoscaling_policies, and list_workloads to discover exact names and workload identities. Lists are summaries: follow data.pageInfo.nextCursor while hasMore is true, then use the corresponding get tool for exact configuration. Keep filters, sort, and limit unchanged while following a cursor. An omitted field is not necessarily zero, false, or unsupported; list projections, old agents, and version-specific defaults can omit it.
Default provenance
There are three distinct defaults: an omitted CRD field’s controller/schema behavior, a new Console form’s starting values, and a named preset saved by the server. Existing presets are not a live template for all policies. Always read the saved spec before proposing a change.
For example, the new RecommendationPolicy form starts with CPU/Memory P95/P99, history 24h/72h, buffers 30%/50%, and evaluation 30s. The server’s balanced preset uses P95/P99, 24h/48h, 10%/20%, evaluation 1m, and request minimums 25%/30%. Neither set is an omitted-field default. Presets can have been edited, and their stored names do not prove their current contents.
Cluster configuration
All paths in this table are relative to data.configuration from get_workload_autoscaler_configuration. These are management settings; they are not fields to add to an AutoscalingPolicy.
| Console concept / setting | Field | Type / units | Default source and interpretation |
|---|---|---|---|
| Feature availability | allowWorkloadAutoscaler | Boolean | Organization-managed entitlement; database starts false. Not an installation or readiness signal. |
| Enable WA | enableWorkloadAutoscaler | Boolean | Database starts true. Disabling removes related cluster configurations; assess policy-removal behavior first. |
| Installation | workloadAutoscalerInstalled | Boolean | Database starts false; observed installation state, not an instruction to install by editing this flag. |
| Installed version | workloadAutoscalerVersion | Version string | Empty until reported. Compare it with the feature’s required components; do not infer support from Console visibility. |
| Automatically optimize new workloads | enableNewWorkloadsProactiveUpdate | Boolean | Database starts false. Applies to eligible workloads created after the most recent enablement time, after recommendation readiness; does not bulk-enable every existing workload. |
| Initial data-window check | enableInitialOptimizationDataWindowCheck | Boolean | Database starts true. Gates first optimization until sufficient history is collected. Disabling it does not manufacture missing samples or bypass other readiness failures. |
| Update rate quota | limiterQuotaPerWindow | Positive integer, quota per window | Database starts 5; synced into WA’s shared update/eviction limiter. Read the saved value instead of treating this as a per-policy quota. |
| Update rate burst | limiterBurst | Positive integer | Database starts 10; burst capacity, not a workload replica count. |
| Update rate window | limiterWindowSeconds | Positive integer, seconds | Database starts 30. Interpret quota, burst, and window together. |
| Preempted Pod garbage collection | enablePreemptedPodGC | Boolean | Database starts true; housekeeping, not a resource-sizing policy. |
| Preempted Pod retention | preemptedPodGCTTL | Go duration string | Database starts 30m; retention setting for preempted-Pod cleanup. |
| Audit compatibility flag | enableWorkloadActivity | Boolean, read-only compatibility | Current management responses report true; writes are ignored. It is not a switch for disabling Audit Log. |
Database defaults describe newly created records, not a migration guarantee for existing clusters. The UI may use fallback values while data is unavailable; those are not authoritative saved configuration.
RecommendationPolicy: ordinary resource calculation
The policy name is returned at data.name and corresponds to Kubernetes metadata.name. In this section, spec.* means both the CRD path and get_recommendation_policy → data.spec.*. CPU quantities use Kubernetes CPU units (m or cores); memory uses quantities such as Mi and Gi. Percentage values are strings ending in %, not decimal fractions.
| Console field / group | Canonical path | Type / allowed values | Omitted behavior and effect |
|---|---|---|---|
| Strategy Type | spec.strategyType | percentile | Required; no alternative strategy is currently supported. |
| CPU / Memory Percentile | spec.strategyPercentile.cpu, .memory | Integer 50–100 | Set both explicitly for percentile calculation. A higher percentile covers more observed usage; it is not a CPU-utilization target. |
| CPU / Memory History Window | spec.historyWindowDuration.cpu, .memory | Positive duration strings | Required historical lookback, independently per resource. Console hours/days serialize to duration strings; there is no universal omitted lookback. |
| Evaluation Period | spec.evaluationPeriod | Positive duration string | Required normal recalculation interval once Ready; not the lookback. Pending readiness and changed inputs can cause earlier reevaluation. |
| CPU / Memory Buffer | spec.buffer.cpu, .memory | Non-negative quantity or percentage | Omitted means no configured extra buffer. A percentage increases each container’s raw recommendation; an absolute value is apportioned across containers. |
| Request Min | spec.limits.requestMin.cpu, .memory | Quantity or percentage | Omitted means no user-specified minimum for that resource, not permission for zero-sized recommendations. Percentages use that container’s recorded original Request. |
| Request Max | spec.limits.requestMax.cpu, .memory | Quantity or percentage | Omitted means no user-specified maximum; Kubernetes Limits and controller protections still apply. Percentages use the original Request, not current usage. |
See RecommendationPolicy for calculation examples and the Resource Limits rules. Important interactions:
- Ordinary sizing applies Buffer, Request Min/Max, and Limit Policy constraints; later minimum-resource protection, available CPU PSI protection, and OOM handling can affect the result. Do not promise that every final target is exactly a clamped percentile.
- Percentage Min/Max is skipped only for a container-resource pair lacking an original Request. Kubernetes may have defaulted a missing Request from a Limit; inspect the recorded baseline.
- Absolute Buffer is request-share based and requires explicit requests for the resource. Absolute bounds use request shares when all requests are present, otherwise recommendation shares. Some share calculations have a 10% floor and rounding; distributed amounts need not sum exactly to the configured Pod-level amount.
- Container Buffer changes container resource recommendations, not the JVM-specific Xms/Xmx recommendation. Heap Buffer is a separate setting.
PSI applicability
CPU PSI protection is controller behavior, not an additional editable RecommendationPolicy field. On controllers that implement it, CPU pressure can preserve more of the original CPU Request during down-sizing. Memory or I/O pressure charts do not imply Memory/I/O PSI-driven sizing. Do not infer CPU PSI support merely because get_workload_runtime_metrics accepts metric: "pressure"; chart collection and recommendation support are separate capabilities. Verify the installed controller version; no universal minimum release is asserted here.
RecommendationPolicy: JVM settings
All paths are below spec.jvm / data.spec.jvm. They affect eligible Java containers only when Memory is managed and the effective AutoscalingPolicy has disableRuntimeOptimization: false. Runtime detection and JVM metrics must be available. An omitted JVM object preserves the controller’s existing JVM calculation; it does not turn JVM optimization off.
| Console field | Canonical path | Type / allowed values | Omitted behavior and interactions |
|---|---|---|---|
| Recent Non-Heap Window | spec.jvm.recentNonHeapWindow | Positive duration string | Controller default 2h. Uses the larger non-heap estimate from the historical and recent windows. |
| Min HeapXms Ratio Of Memory | spec.jvm.minHeapXmsRatioOfMemory | Numeric string, 0 inclusive to 1 exclusive | Controller default "0.25". Console percentage display must be converted to a ratio, e.g. 25% → "0.25". Final heap ceilings can override this minimum relationship. |
| Xms Min | spec.jvm.minHeapXms | Positive memory quantity; percentage on compatible managed clusters | No configured bound when omitted. Raising it may increase Xmx and total container Memory. |
| Xms Max | spec.jvm.maxHeapXms | Positive memory quantity; percentage on compatible managed clusters | No configured bound. Caps Xms without recalculating Xmx from the capped Xms. |
| Xmx Min | spec.jvm.minHeapXmx | Positive memory quantity; percentage on compatible managed clusters | No configured bound. Raises Xmx and adjusts total Memory while preserving the non-heap allowance. |
| Xmx Max | spec.jvm.maxHeapXmx | Positive memory quantity; percentage on compatible managed clusters | No configured bound. Final Xmx also caps Xms, even if this overrides Xms Min or its minimum ratio. |
| Heap Buffer | spec.jvm.heapBuffer | Non-negative memory quantity or percentage | No configured extra heap buffer. Adds headroom to calculated Xms to derive Xmx; optional bounds apply afterward. |
| Heap Used Percentile | spec.jvm.heapUsedPercentile | Integer 20–100 | Controller default P20. A separate heap-used baseline, not a replacement for the regular Memory percentile. |
Heap bounds require a positive whole-Mi result: minimums round up and maximums round down; a maximum must be at least 1Mi. For each row, resolved Min must not exceed Max. Use the installed schema/webhook for quantity constraints rather than assuming that every parseable quantity is accepted.
Percentages on Xms use the original effective JVM InitialHeapSize; percentages on Xmx use the original effective MaxHeapSize. These are pre-optimization configuration baselines, not heap usage or container Requests, and percentages may exceed 100%. Missing required baselines keep the recommendation NotReady; they must not be replaced with zero or a guessed memory ratio. Selfhost does not support percentage heap bounds in the documented release.
Read the heap baseline, upgrade, and rollback guidance before enabling percentages. CRDs, node agent, webhook, controller, and management support must all match. Bounds do not cap total container Memory. Conflicts with container Request Max or Limit Policy can fail readiness and retain the last successful recommendation.
Heap changes require replacement Pods; a resource-only resize cannot change a running JVM’s heap. See Java application integration for recognized standalone flags, environment-variable integration, valueFrom limitations, and explicit InitialHeapSize conflicts.
AutoscalingPolicy: selection and application
Unless noted, spec.* maps to get_autoscaling_policy → data.spec.*. The name is data.name; active management state is data.enable.
| Console field / group | Canonical path | Type / allowed values | Omitted behavior and interactions |
|---|---|---|---|
| Enable | data.enable (management only) | Boolean | New Console policy starts false. Disabling removes its cluster resource and can trigger On Policy Removal; it is not the same as choosing mode off. |
| Priority | spec.priority | Signed 32-bit integer | Defaults 0. Highest matching priority wins; equal priority uses the oldest-created policy. |
| Recommendation Policy | spec.recommendationPolicyName | Existing RecommendationPolicy name | Required. A referenced policy cannot simply be removed while still in use. |
| Workload Kind | spec.targetRefs[].kind | Deployment, StatefulSet, DaemonSet | Required per target; a ReplicaSet is not an independently supported top-level target. |
| API Version | spec.targetRefs[].apiVersion | apps/v1 for the supported workload kinds | Required by the policy validation webhook. |
| Name / Namespace | spec.targetRefs[].name, .namespace | String or supported shell-style glob | Empty matches all in that dimension. An empty targetRefs array matches no workloads, not every workload. |
| Label Selector | spec.targetRefs[].labelSelector.matchLabels, .matchExpressions | Kubernetes selectors | ANDed with the other fields within a target; targets are ORed. Expressions contain key, operator (In, NotIn, Exists, DoesNotExist), and applicable values. |
| Update Resources | spec.updateResources | Set of cpu, memory | Omitted selects both. Console requires a nonempty selection. CPU-only management does not enable JVM heap changes. |
| CPU / Memory Drift Threshold | spec.driftThresholds.cpu, .memory | Quantity or percentage | Omitted controller behavior is 10% per resource. Percentage drift is measured against current Pod resources. Console accepts 5–100% for percentage entries; presets may save different explicit values. |
| On Policy Removal | spec.onPolicyRemoval | off, recreate, inplace | Omitted defaults off. Controls restoration toward the recorded baseline when the APC is deleted, not the normal optimization mode. Restoration may disrupt Pods. |
| Disable Runtime Optimization | spec.disableRuntimeOptimization | Boolean | Omitted spec defaults false; new Console forms start true. True disables JVM-specific sizing/heap mutation but does not stop generic resource calculation or runtime-language detection. |
See target matching, drift thresholds, and policy removal.
For newly initialized server presets, readonly is enabled with ordinary mode off, while cloudpilot starts disabled. Both explicitly set runtime optimization disabled and 5% drift thresholds; their removal behavior differs (off versus recreate). These are saved preset choices, not omitted-field defaults or proof of an existing cluster’s current settings.
Update Schedule
| Console field | Canonical path | Type / allowed values | Behavior |
|---|---|---|---|
| Schedule name | spec.updateSchedule[].name | Nonempty string | Identifies a rule; its position controls precedence, not its name. |
| Cron Expression | spec.updateSchedule[].schedule | Standard cron string | Must be paired with Duration. Console timezone is encoded in this string as TZ=<IANA-zone> <cron>; there is no separate timezone spec field. Without a timezone, use the guide’s UTC behavior. |
| Duration | spec.updateSchedule[].duration | Positive duration for a windowed rule | Omit both schedule and duration for an always-active rule; do not submit only one. |
| Update Mode | spec.updateSchedule[].mode | off, oncreate, recreate, inplace | Later active rules win. Empty schedule list or no active rule resolves to off. |
oncreate applies normal recommendations at Pod admission without proactive ordinary replacement. recreate permits replacement; inplace requests resize subject to platform restrictions and fallback; off pauses ordinary application without deleting the policy. Off is not a guarantee that every lifecycle action stops: already-boosted Pods still need Startup Boost cleanup. For complete admission and lifecycle rules, see Update Schedule.
Limit Policies
Configure CPU and Memory independently under spec.limitPolicies.cpu and .memory. Select at most one policy field per resource. An omitted resource policy uses Keep; the new Console form instead explicitly starts with Remove for both resources.
| Console option | Canonical per-resource field | Value | Effect |
|---|---|---|---|
| Keep | keepLimit | true | Preserve the baseline Limit; sizing may have to respect it. |
| Remove | removeLimit | true | Remove this resource Limit when applied; do not use where a hard cap is required without reviewing the consequences. |
| Multiplier | multiplier | Numeric string 1–5 | Derive Limit from the recommended Request times the factor. |
| Auto Headroom | autoHeadroom | Numeric string 1–5 | With an existing Limit, increase it when the calculated target is higher; never lower it. If no Limit exists, keep it unlimited. |
The legacy singular limitPolicy is not the canonical current per-resource configuration. Do not generate new policies from a legacy UI compatibility field. See Limit Policies for application timing and QoS interactions.
InPlace Fallback
| Console field | Canonical path | Type / allowed values | Omitted behavior |
|---|---|---|---|
| Default fallback | spec.inPlaceFallback.defaultPolicy | recreate, hold | Controller defaults recreate. Console target-aware defaults can choose hold for DaemonSet targets; inspect the saved value. |
| Per-reason fallback | spec.inPlaceFallback.reasonPolicies.<reason> | recreate, hold | Missing reason uses the default. hold avoids fallback recreation, but can leave the target unapplied. |
Supported reason keys are PodResizePending, QoSChangeForbidden, MemoryLimitsAddForbidden, ResourceLimitsRemoveForbidden, ResourceRequestsRemoveForbidden, ResourceMemoryLimitCannotBeDecreased, and JVMHeapDrift. inplace does not imply a no-restart guarantee when fallback is recreate or a container’s ResizePolicy requires restart. Review limitations and HPA coexistence before selecting a fallback.
Startup Boost
Paths below are under spec.resourceStartupBoost. Dedicated startup policies and nested resource selection require matching CRDs/controller/management support; older releases can have only the legacy multiplier path. Do not submit a newer field merely because it exists in this reference.
| Console field | Canonical path | Type / allowed values | Omitted / draft behavior and effect |
|---|---|---|---|
| Enable Startup Boost | spec.resourceStartupBoost.enabled | Boolean | Omitted false. Does not require JVM runtime optimization; it is a resource startup feature. |
| Startup Resources | spec.resourceStartupBoost.updateResources | Nonempty set of cpu, memory | Omitted selects both, intersected with top-level Update Resources. Enabled effective selection must be nonempty. |
| Min Boost | spec.resourceStartupBoost.minBoostDuration | Non-negative duration string | Omitted zero controller duration; new Console draft starts 5m. Minimum elapsed time since Pod creation, not the history lookback. |
| Min Ready | spec.resourceStartupBoost.minReadyDuration | Non-negative duration string | Omitted zero controller duration; new Console draft starts 2m. Minimum continuous Ready time before reversion. |
| Startup Recommendation Policy | spec.resourceStartupBoost.recommendationPolicyName | Existing RecommendationPolicy name | Must differ from the steady policy. Required by the current enabled-policy editor; there is no universal implicit policy. New drafts may select startup-balanced if available. |
| Legacy multipliers | spec.resourceStartupBoost.resourceMultipliers.cpu, .memory | Numeric strings 1–5 | Compatibility-only, hidden in current editor. A configured startup policy takes precedence; do not add multipliers to new configurations. |
The dedicated startup policy computes generic resource recommendations, not JVM heaps. Within its effective resource scope, startup Requests use the greater of steady and startup recommendations. CPU Limits follow the applicable Limit Policy; Memory Limits remain steady-derived and constrain startup Memory Requests. Missing or stale configured startup-policy results do not silently fall back to multipliers or guessed values.
Both Min Boost and Min Ready gates must finish before reversion. Disabling the feature stops newly admitted boosts; previously boosted Pods retain their original lifecycle windows and still revert. Check the startup readiness and cleanup rules rather than treating the current update mode as the sole gate.
Workload overrides and effective state
Apply user annotations/labels to workload metadata, not arbitrary Pod metadata or the generated APC spec. Console overrides and user annotations are distinct sources; annotations take precedence over the corresponding system-managed label. Read the effective workload result after reconciliation.
| Workload control | Canonical metadata key | Values / precedence | Readback |
|---|---|---|---|
| Pause workload optimization | Annotation evpa.cloudpilot.ai/disable-proactive-update | String "true" / "false"; annotation overrides the label. True also blocks recommendation application at admission, not only proactive eviction. | get_workload_detail → data.proactiveUpdateDisabled, data.proactiveUpdateDisabledOverriddenByAnnotation |
| Override RecommendationPolicy | Annotation evpa.cloudpilot.ai/recommendation-policy | Existing policy name; annotation overrides the Console-managed label. Remove the override to return to policy assignment. | data.recommendationPolicyName, data.recommendationPolicyOverriddenByAnnotation, data.recommendationPolicyOverriddenByConsole |
| Override container runtime | Label evpa.cloudpilot.ai/container-runtime-language.<container-name> | java, golang, python, nodejs, dotnet, ruby, php; container must exist. Does not bypass Disable Runtime Optimization. | data.workloadRuntimeProfile.containerRuntimeLanguages |
| Override primary container | Label evpa.cloudpilot.ai/primary-container | Existing template container name. Without a valid override, controller heuristics choose the primary container. | data.workloadRuntimeProfile.primaryContainerName |
| Runtime selection label | Label evpa.cloudpilot.ai/primary-runtime-language | System-managed; use for target selectors, not as a user override. | Workload metadata / effective runtime profile |
See Workload Configuration. Recommendations can continue while application is paused. A saved override does not create an otherwise missing workload target or supply missing metrics.
What MCP can and cannot prove
| Question | Available read / path | Interpretation |
|---|---|---|
| Which policy currently owns this workload? | get_workload_detail → data.autoscalingPolicyName, data.recommendationPolicyName, override flags | Effective management projection; compare it with the exact policy detail. |
| Is the workload ready and optimized? | data.workloadState, data.optimizationState, data.replicas, data.optimizedReplicas, data.updateMode | Workload Ready is not identical to recommendation Ready. Optimization states can include Ready, Recommending, Updating, and Deleting. |
| What changed in sizing? | data.originalResources, data.recommendedResources, data.resourcesDelta, data.limitPolicies | Choose scope: "pod" or "workload" consistently. These aggregates do not expose each container’s original JVM heap baseline. |
| Which runtimes and Java version? | data.workloadRuntimeProfile, data.javaInfo.javaVersion | Detection metadata alone does not prove heap mutation is enabled. |
| What is the runtime history? | get_workload_runtime_metrics with metric: "jvm" or "pressure" | JVM memory series use GiB, GC duration seconds, pressure percent. Empty series mean no collected samples, not zero usage. |
| Which workloads does an AP report managing? | get_autoscaling_policy → data.status.managedWorkloads, .observedGeneration | Status can be absent before application or stale before reconciliation; it is not a full set of APC readiness conditions. |
| Why is JVM baseline or startup sizing NotReady? | Console diagnostics or installed APC status.conditions, status.jvmHeapBaselines, startup status | Current get_workload_detail does not return these full diagnostics. Do not invent an MCP data.conditions or data.javaInfo.heapBaseline field. |
For low-level diagnosis, the APC conditions include RecommendationReady, JVMHeapBaselineReady, UpdateReady, and RuntimeProfileDetection; inspect their status, reason, message, and observed generation. Startup recommendations and OOM boosts also have separate APC status fields. These are observed/controller-owned values, not settings to change to force Ready. See OOM status guidance.
MCP responses also contain observation time, source status, and warnings. A successful tool call proves the read succeeded, not that all cluster components are Ready or every returned status is current. If diagnostics are not exposed by the installed MCP, explicitly state the gap and use the Console or authorized Kubernetes read; never infer readiness from missing fields.
Recommended workflows
Observe first, then enable one bounded target
- Read cluster installation/version, list policies, then fetch exact AP/RP specs and one representative workload. Confirm target matches, recorded baseline, and availability of metrics.
- Keep an enabled policy in ordinary mode
offfor observation, or use the existingreadonlypolicy after reading its actual spec. A disabled management policy is removed from the cluster and is not an equivalent observation mode. - Select a narrow, non-overlapping target or intentional higher priority; choose resources, Limit Policy, fallback, and removal behavior explicitly. Review the estimated recommendation against workload health and available capacity.
- Apply through the authorized Console workflow, initially using OnCreate if proactive restarts are not acceptable. Verify effective assignment, update mode, optimized replicas, and application health before expanding the target. The read tools listed here do not execute these writes.
Coexist with HPA
Read the HPA’s metric type and resource targets before changing Requests: utilization-based HPA uses Requests as its denominator. Avoid having WA and HPA independently alter the same resource signal without a coordinated design. A common starting point is Memory-only WA when HPA owns CPU utilization, but verify the application’s requirements rather than presenting that as a universal setting. Keep CPU unchanged, inspect spec.updateResources, and verify HPA replicas, latency, and Memory behavior after rollout. See HPA coexistence.
Enable JVM bounds without guessing the baseline
- Confirm Java detection, Memory management, runtime optimization enabled, and supported controller/CRD/node-agent versions. Check the application integration and any explicit heap flags.
- For percentage bounds, inspect the original effective heap baseline and
JVMHeapBaselineReadyin Console/APC. If unavailable, wait or use an explicitly reviewed absolute bound; do not substitute current heap usage or container Memory. - Validate the resolved Min/Max and container Memory constraints. Read the fallback policy: JVM heap drift may require recreation. After replacement, verify effective JVM flags, heap/GC history, OOM signals, and application health; removing bounds restores ordinary calculation, not necessarily the application’s original heap flags.