Skip to content

KEDA Best Practices

Configure the ScaledObject that owns the workload. KEDA manages activation and return to zero; HPA or KPA manages active replicas. Use Kubernetes Autoscaling Best Practices for requests, probes and shutdown.

The activation threshold controls whether a workload wakes from zero; the scaling target controls capacity once it is running. Activation requires a value greater than the threshold: activationQueueLength: "5" leaves five queued messages waiting while the workload is at zero. Keep the default activation threshold of zero unless batching is intentional. Use the selected scaler’s activation parameter.

For external metrics, use AverageValue for total work divided among replicas. Value compares the metric directly with its target and multiplies the ratio by the current replica count.

With three replicas, a metric value of 20 and a target of 5, the HPA recommendations before limits and stabilization are:

metricTypeCalculationReplicas
AverageValueceil(20 / 5)4
Valueceil(3 × 20 / 5)12

Set metricType on the trigger and check the metric’s units and aggregation. See the trigger reference.

A Prometheus scaler query must return one scalar or vector element. When an empty result means telemetry is missing, set ignoreNullValues: "false" under trigger metadata so it produces an error and can engage configured fallback. The default "true" accepts empty results. Avoid query expressions that replace missing data with zero unless absence really means no work.

Test both a valid zero value and a missing series; they should have different failure behavior.

To stop when idle but activate with at least three replicas, add this fragment under ScaledObject.spec:

idleReplicaCount: 0
minReplicaCount: 3
maxReplicaCount: 10

Native HPA supports only zero for idleReplicaCount. For a permanent warm floor, omit it and set minReplicaCount to the required count. Use initialCooldownPeriod for a grace period after ScaledObject creation; it does not restart on every workload activation. See idle replica behavior.

Workloads with predictable operating hours can consume resources while nobody needs them. Scaling them to zero outside those hours reduces idle resource usage while bringing them back automatically for the next running window.

Define when the workload should run with a Cron trigger and set minReplicaCount: 0 for off-hours scale-to-zero. Set desiredReplicas to a positive count for the running window, not "0" for a shutdown window.

This example runs a Deployment during weekdays from 08:00 to 18:00 in Prague:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: app-working-hours
namespace: default
spec:
scaleTargetRef:
name: app
minReplicaCount: 0
maxReplicaCount: 2
cooldownPeriod: 300
triggers:
- type: cron
metadata:
timezone: Europe/Prague
start: "0 8 * * 1-5"
end: "0 18 * * 1-5"
desiredReplicas: "2"

With only this trigger, the Deployment runs at two replicas during the window and returns to zero after the 300-second cooldown. Apply a ScaledObject to each workload; one schedule does not shut down a whole namespace.

Other external triggers can keep workloads running or reactivate them off-hours: Cron sets a replica floor, not a shutdown override. For advanced scheduling, use Kedify ScalingPolicy to manage multiple targets, scheduled replica bounds and action priorities. To keep ScaledObject workloads at zero regardless of demand, configure the shutdown action’s pauseConfig with paused: true and replicas: 0.

Test shutdown and restart transitions before rollout. See the KEDA Cron scaler guidance for details.

Fallback defines a replica target after repeated metric failures. The fallback reference supports Value and AverageValue, excluding CPU/memory triggers and ScaledJobs. Check your installed KEDA version before applying it.

Add this fragment under ScaledObject.spec; keep your existing target and triggers:

fallback:
failureThreshold: 3
replicas: 6
behavior: currentReplicasIfHigher

currentReplicasIfHigher uses the larger of the current count and six, avoiding a lower fallback target during an outage. Use static for a fixed fallback target. Size it from measured capacity, then test metric failure and recovery both from zero and while running. Fallback does not guarantee pod readiness. See fallback behavior.

This ScaledObject.spec fragment permits immediate scale-up and smooths scale-down over five minutes:

advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60

These values are an example, not capacity guarantees. A scale-up stabilization window delays reactions to short spikes; use one only when the latency budget permits it. Longer scale-down windows retain more idle capacity. Test a demand spike and a return to idle, and inspect the generated HPA/KPA behavior before changing the window again.

Understand Polling and Autoscaler Evaluation Intervals

Section titled “Understand Polling and Autoscaler Evaluation Intervals”
SettingControlsTradeoff
pollingIntervalKEDA trigger checks, including activationFaster polling increases source/API traffic
cooldownPeriodKEDA’s return to zero after inactivityLonger cooldown keeps warm capacity longer
Trigger useCachedMetricsReuse of the metric refreshed on KEDA’s polling cycleFaster autoscaler evaluation can still read the same cached value
HPA sync periodNative HPA’s active replica evaluationCluster-wide control-plane setting, commonly 15 seconds
autoscaling.kedify.io/sync-period-secondsPer-workload KPA evaluationLower intervals increase controller and metric load

Changing pollingInterval does not change HPA’s sync period. Configure KPA cadence separately. Use performance measurements before increasing controller request rates.

For supported triggers, enable caching at the same level as metadata:

useCachedMetrics: true

The cache refreshes on pollingInterval; autoscaler evaluations reuse values between refreshes. This reduces source queries but delays visibility of changes. Choose an interval that fits the reaction-time budget. CPU, memory and Cron triggers do not support this cache.

Scaling modifiers combine named triggers into one metric. The following fragment assumes existing triggers named queue1 and queue2 with compatible units and equal per-item processing cost:

advanced:
scalingModifiers:
formula: "queue1 + queue2"
target: "5"
activationTarget: "0"
metricType: AverageValue

Here, one replica is requested per five combined queued items. An average would halve that demand. Check metric units, target semantics and failure behavior before combining triggers. Test each source independently, simultaneous demand and a failed source. For source-specific configuration and authentication, see built-in KEDA scalers.

For releases supporting per-trigger fallback, fallback.behavior: scalingModifiers passes failed triggers as nil. A formula such as primary ?? backup uses the first healthy metric; if both fail, fallback.replicas applies. Without this behavior, trigger fallback bypasses the formula.

For long-running tasks, consider ScaledJobs. The default rollout deletes existing Jobs when the ScaledJob changes. To let running Jobs finish and apply the new configuration only to new Jobs, add this under ScaledJob.spec:

rollout:
strategy: gradual

Choose the scaling strategy to match queue accounting: accurate is intended for metrics that exclude locked messages. Test an update with a Job still running and verify completion and retry behavior. See rollout semantics.

Use TriggerAuthentication in the ScaledObject’s namespace. Use ClusterTriggerAuthentication only when credentials need to be shared across namespaces; its Secret references default to the KEDA installation namespace. Keep credentials out of trigger metadata, grant only required source permissions, and verify fresh metrics after credential rotation. See authentication scopes.

KEDA webhooks default to failurePolicy: Ignore, allowing matching writes when the webhook is unavailable. Use Fail when validation must be enforced; webhook downtime will then block those writes. Keep ownership validation enabled and verify webhook availability before changing the policy. See validation enforcement.

Autoscaling Checks verify the control-plane path. Set a threshold from the expected timing of the enabled check; for example:

kedify_autoscaling_check_duration_seconds > 300

Check the overall result and step labels as well as elapsed time. The compatibility labels hpa_metric and hpa_active apply to both HPA and KPA. Use workload diagnostics for application failures.