KEDA: Event-Driven Autoscaling in Kubernetes

KEDA: Event-Driven Autoscaling in Kubernetes

A zero-to-production guide to scaling workloads by what is actually happening in your system: queue depth, stream lag, schedules and custom metrics, including scaling all the way down to zero and back.

Picture a busy pizza shop. On a quiet Tuesday afternoon, one cook is plenty. On Friday night, orders pour in and you need eight cooks. A smart manager does not wait until the kitchen looks hot and sweaty before calling in help. The manager looks at the order screen. When fifty tickets pile up, more cooks are called. When the screen is empty for an hour, most cooks go home and the shop saves money on wages.

Most Kubernetes clusters do not have a manager like that. The built-in autoscaler looks at how hot the kitchen is, meaning how much CPU and memory the running containers are using, not at how many orders are waiting. For many applications that is the wrong signal. A worker that reads messages from a queue may use almost no CPU while a million messages pile up behind it. A nightly report generator may need to run only when a file arrives. An API that is used only during business hours may sit idle, and still cost money, for sixteen hours a day.

KEDA, which stands for Kubernetes Event-Driven Autoscaling, is the manager who reads the order screen. It watches real events and real backlogs from more than fifty kinds of systems, and tells Kubernetes how many copies of your application to run, including none at all. This guide teaches KEDA from the very beginning. Every new word is explained when it first appears, every big idea comes with an everyday comparison, and each chapter builds on the previous one. By the end you will know how to design, secure, tune and operate event-driven autoscaling in production.

1Why CPU-Based Scaling Is Not Enough

Before we meet KEDA, we need to see the problem it solves. This chapter shows where the standard approach to autoscaling works well, and where it quietly fails.

What autoscaling means

Autoscaling means that a system adds or removes capacity automatically as demand changes. In Kubernetes, the unit of capacity is usually a Pod. A Pod is the smallest runnable piece in Kubernetes, and it holds one or more containers. If demand goes up, we want more Pods. If demand goes down, we want fewer Pods, so we are not paying for machines that do nothing.

The classic signal: CPU and memory

The standard Kubernetes autoscaler looks at how busy each Pod is. If the average CPU use across Pods is high, it adds Pods. If it is low, it removes some. This works nicely for web servers that do real work for every request, because more requests mean more CPU use.

Where the classic signal breaks

  • Queue workers. A worker takes a message, calls a slow outside service, and waits. While it waits it uses almost no CPU. Ten thousand messages can be waiting in the queue while CPU shows a calm 5 percent, so no new workers start.
  • Stream processors. A program that reads from a stream such as Apache Kafka falls behind when data arrives faster than it can process. The measure that matters is lag, the number of unread messages, which CPU cannot show.
  • Scheduled work. Some applications are needed only at known times, such as a trading dashboard from 9 a.m. to 5 p.m. CPU only reacts after the rush has already started.
  • Rare events. A function that runs when a file is uploaded may be needed ten times a day. Keeping one Pod running all day just to wait is waste. Plain CPU-based scaling cannot go below one Pod.
  • Delayed reaction. CPU rises only after a flood of work has arrived, so the system always starts scaling late.
Everyday Analogy

Judging a restaurant’s need for staff by how sweaty the cooks look is like judging a queue by CPU. If the cooks are waiting for the oven, they look relaxed even though fifty customers are lined up outside. The right signal is the length of the line, not the mood of the kitchen.

i
Key Idea

Scale on the signal that best predicts the work waiting to be done. For web servers that may be CPU or request rate. For event-driven systems it is almost always a backlog, a lag, a rate or a schedule.

2Kubernetes Autoscaling Basics

KEDA does not replace Kubernetes autoscaling. It builds on it. To understand KEDA you must first understand the parts it connects to.

The three built-in autoscalers

HPA

Horizontal Pod Autoscaler

Changes the number of Pods. Adds copies when load rises and removes them when it falls. This is the one KEDA works with.

VPA

Vertical Pod Autoscaler

Changes the size of each Pod, meaning how much CPU and memory it requests, instead of how many Pods there are.

CA

Cluster Autoscaler

Adds or removes the machines, called nodes, that Pods run on. It reacts when Pods cannot be placed for lack of room. Newer tools such as Karpenter do a similar job.

How the HPA decides

The Horizontal Pod Autoscaler, or HPA, is a control loop that runs inside Kubernetes. By default it wakes up about every 15 seconds. Each time, it asks a metrics source for a number, compares it with a target, and calculates how many Pods it wants. The idea behind the calculation is simple: if you have 4 Pods and each is at double the target load, you need about 8 Pods. If each is at half the target, you need about 2.

Where the HPA gets its numbers

The HPA can read three kinds of metrics. Resource metrics are CPU and memory, served by a component called the metrics server. Custom metrics describe objects inside the cluster, such as requests per second on a Pod. External metrics come from systems outside the cluster, such as the length of a cloud queue. Kubernetes defines an official programming interface for external metrics, so any program can register itself to answer questions about them.

What the HPA cannot do alone

  • It needs a program that actually fetches metrics from queues, streams and databases, and translates them into the official interface. Writing such an adapter for every system is a lot of work.
  • It cannot scale a workload to zero by default. Its minimum is one Pod.
  • It cannot create short-lived jobs in response to individual events.
Everyday Analogy

The HPA is a very good thermostat. It can turn heating up or down perfectly, but only if someone gives it a thermometer reading. KEDA is the set of thermometers for every room and every kind of weather that your thermostat did not know how to read.

i
Good to Know

KEDA does not do the HPA’s job a second time. It uses the real Kubernetes HPA for scaling between one Pod and many Pods, and adds its own logic for the step between zero and one. This split is explained in detail in Chapter 9.

3Events, Queues and Streams: A Quick Primer

KEDA is named after events, so it helps to know what an event-driven system looks like and which signals it produces.

What an event-driven system is

In an event-driven system, parts of the application talk to each other by sending small messages called events, instead of calling each other directly and waiting for answers. A shop website, for instance, does not charge the card, reserve stock, send email and update analytics in one long call. It drops an “order placed” event into a queue, and separate workers pick it up and do their own part. This design makes systems more flexible and more resilient, because a slow worker does not hold up the website.

Queues and streams

A queue is a line of messages. Producers add messages at the back, and consumers take them from the front. Each message is usually handled by one consumer and then removed. Examples include Amazon SQS, RabbitMQ and Azure Service Bus. A stream or log is a long record of events that consumers read at their own pace, each keeping track of its position. Apache Kafka is the best-known example. The gap between the newest event and the position a consumer has reached is called lag.

Signals that event-driven systems produce

SignalWhat it tells youTypical source
Queue lengthHow many messages are waiting to be handledSQS, RabbitMQ, Service Bus, Redis lists
Consumer lagHow far behind consumers are in a streamKafka, Pulsar, Kinesis
Message rateHow fast messages arrive or are handledPrometheus metrics, broker metrics
TimeWhether the current time is inside a busy windowCron-style schedules
Custom valueAny business number you can measureDatabases, HTTP endpoints, monitoring systems
Everyday Analogy

A queue is like the line at a bank. Each customer is served once and leaves. A stream is like a recorded TV series: many viewers can watch, each at their own place in the story, and the “lag” is how many episodes you are behind the latest one. Different shapes, but both tell you how much work is waiting for you.

4What KEDA Is and Where It Came From

Now we can describe KEDA properly: what it does, who made it, and how it fits with the tools you already use.

A short history

KEDA was started in 2019 as a joint project between Microsoft and Red Hat. Microsoft had been building Azure Functions, a service that runs small pieces of code in response to events, and wanted the same event-driven scaling to work on any Kubernetes cluster. The project was accepted into the Cloud Native Computing Foundation (CNCF) as a sandbox project in 2020, moved up to incubating in 2021, and reached the highest level, graduated, in 2023. Graduation means the project has proven maturity, broad adoption and healthy governance.

What KEDA does in one sentence

KEDA is a lightweight add-on for a Kubernetes cluster that watches external event sources and adjusts the number of Pods of your workloads, from zero up to as many as you allow, based on what it sees.

What KEDA is not

  • It is not a message queue. It reads from queues you already have.
  • It is not a replacement for the HPA. It feeds and controls the HPA.
  • It is not a node autoscaler. It adds Pods, and other tools add the machines they run on.
  • It does not require you to rewrite your application. The application keeps doing its normal job, and KEDA decides how many copies run.

Why teams choose it

Breadth

Many event sources

Well over fifty built-in scalers cover queues, streams, databases, monitoring systems, cloud services and schedules.

Savings

Scale to zero

Idle workloads can run no Pods at all, so you pay nothing for compute while nothing happens.

Simplicity

One small object

A single configuration object describes the target, the limits and the triggers. No custom code is needed.

Safety

Built on the HPA

It reuses the proven Kubernetes scaling engine and does not invent a competing one.

Neutral

Works anywhere

It runs on any conformant Kubernetes cluster, in any cloud or in your own data center.

Open

Open source and extensible

Anyone can add a new scaler or write an external one in any language.

i
Naming Note

KEDA is pronounced like “KEH-duh”. The name is an acronym, and you will often see people write it in capitals. It is sometimes confused with Knative, another event-oriented Kubernetes project. We compare them in Chapter 24.

5Architecture and Components

KEDA is made of a few small programs. Each has one clear job, and together they bridge the world of events and the world of Pods.

The big picture

When you install KEDA, it creates a namespace, usually called keda, and starts three groups of Pods there. All your application workloads stay in their own namespaces. KEDA only reaches into them to read their scale and change their replica count.

flowchart TB
  subgraph Sources["External Event Sources"]
    Q["Message queue"]
    K["Kafka stream"]
    P["Prometheus metrics"]
    C["Cron schedule"]
  end
  subgraph Cluster["Kubernetes Cluster"]
    API["API Server"]
    HPA["Horizontal Pod Autoscaler"]
    subgraph KEDA["keda namespace"]
      OP["KEDA Operator - controller and scalers"]
      MS["Metrics API Server - external metrics adapter"]
      WH["Admission Webhooks"]
    end
    subgraph App["Application namespace"]
      SO["ScaledObject"]
      TA["TriggerAuthentication"]
      DEP["Deployment and Pods"]
    end
  end
  SO --> OP
  TA --> OP
  OP -->|"poll for events"| Q
  OP -->|"poll for events"| K
  OP -->|"poll for events"| P
  OP -->|"poll for events"| C
  OP -->|"scale 0 to 1 and 1 to 0"| DEP
  OP -->|"create and manage"| HPA
  HPA -->|"ask for external metrics"| API
  API -->|"forward request"| MS
  MS -->|"fetch values"| OP
  HPA -->|"scale 1 to N"| DEP
  WH -->|"validate objects"| API
Figure 1: KEDA components and how they connect to Kubernetes and event sources

Component by component

ComponentWhat it doesWhy it exists
KEDA operatorWatches KEDA objects, polls event sources through scalers, activates and deactivates workloads (zero to one and back), and creates the HPA objects.It is the brain, and handles the part the HPA cannot: scaling to and from zero.
Metrics API serverAnswers the HPA’s questions about external metrics by passing along the values the operator collects.It plugs KEDA into the official Kubernetes external-metrics interface.
Admission webhooksCheck KEDA objects when they are created or changed and reject mistakes such as two scalers pointing at the same workload.Catches configuration errors early, before they cause confusing behavior.
Custom resource definitionsAdd new object kinds such as ScaledObject, ScaledJob and TriggerAuthentication to the cluster.Lets you manage scaling like any other Kubernetes object.
ScalersSmall plug-in modules inside the operator, one per kind of event source.Each knows how to ask one specific system “how much work is waiting?”
Everyday Analogy

Think of KEDA as a shop manager with an assistant and an inspector. The operator is the manager who watches the order screens and decides when to open or close the kitchen. The metrics server is the assistant who reports the order numbers to the shift supervisor, the HPA. The admission webhooks are the inspector who checks every new instruction for mistakes before it is accepted.

6The ScaledObject: Your Main Control Panel

Almost everything you do in KEDA starts with one object. Learn its parts, and you can read any KEDA configuration you will ever meet.

What a ScaledObject is

A ScaledObject is a Kubernetes object that tells KEDA “scale this workload, between these limits, based on these triggers.” It lives in the same namespace as the workload. You create one for each application you want KEDA to manage.

The important settings, in plain words

SettingMeaningDefault
Scale targetWhich workload to scale. Usually a Deployment, but a StatefulSet or any custom resource that supports the scale interface also works.Required
TriggersOne or more event sources and the thresholds that decide scaling.Required
Minimum replicasThe fewest Pods to keep. Setting zero allows scale to zero.0
Maximum replicasThe most Pods allowed. This is your safety ceiling.100
Polling intervalHow often, in seconds, KEDA checks the event source.30 seconds
Cooldown periodHow long, in seconds, to wait after the last activity before scaling from one Pod down to zero.300 seconds
FallbackWhat to do if KEDA cannot reach the event source. Covered in Chapter 15.Not set
Advanced optionsFine tuning of the underlying HPA, such as how fast it may scale down.HPA defaults

A worked example in words

Imagine a service called “invoice-worker” that reads invoices from an SQS queue and turns them into PDF files. You write a ScaledObject that points at the invoice-worker Deployment. You set the minimum to zero and the maximum to 40. You add one trigger of type SQS queue, naming the queue and saying “target ten messages per Pod.” From then on, if 200 messages are waiting, KEDA wants 20 Pods. If the queue is empty for five minutes, it shrinks the Deployment to zero.

1

Name the target

Point the ScaledObject at the Deployment that holds your worker.

2

Set the limits

Choose a minimum and maximum. The maximum protects downstream systems from being overwhelmed.

3

Add triggers

Describe where the work comes from and how much work one Pod should handle.

4

Provide credentials

Reference a TriggerAuthentication if the event source needs a password or identity. See Chapter 8.

!
Common Trap

Never create your own HPA for a workload that a ScaledObject manages. KEDA creates and owns an HPA for it. Two autoscalers pulling the same Pods in different directions causes flapping, and KEDA’s admission webhook will usually reject the attempt.

7Scalers: The Library of Event Sources

A scaler is the part of KEDA that knows how to talk to one kind of system. This is where KEDA gets its enormous reach.

What a scaler does

A scaler connects to a particular system, asks a question such as “how many messages are waiting?”, and returns two things: a number, and a yes-or-no answer to “is there any work at all?” The yes-or-no answer is called activity. It decides whether the workload should be running at all. The number drives how many Pods to run.

The families of scalers

FamilyExamplesWhat it measures
Message queuesAmazon SQS, RabbitMQ, Azure Service Bus, Google Pub/Sub, IBM MQNumber of waiting messages
Streams and logsApache Kafka, Apache Pulsar, AWS Kinesis, Azure Event HubsConsumer lag behind the newest event
Databases and cachesRedis lists and streams, PostgreSQL, MySQL, MongoDB, ElasticsearchRow counts, list lengths, or the result of a query
Monitoring systemsPrometheus, Datadog, New Relic, GraphiteAny metric expressed as a query
Cloud servicesAzure Blob, Azure Pipelines, AWS CloudWatch, Google Cloud StorageFiles, builds and cloud metrics
Time-basedCronWhether the clock is inside a scheduled window
Resource and genericCPU, memory, metrics API, external gRPCIn-cluster usage, any HTTP endpoint, or your own code

Two numbers every trigger has

Almost every trigger has two main thresholds. The target value says how much work one Pod should handle, for example “ten messages per Pod.” This drives the Pod count once the workload is running. The activation value says how much work must exist before the first Pod is started at all, for example “at least one message.” Keeping these two ideas apart makes scale-to-zero behavior predictable. Chapter 10 explains why.

Everyday Analogy

Scalers are like different kinds of gauges in a control room. One reads the pressure in a pipe, another the temperature of a tank, another the water level behind a dam. They all report in different units, but the control room operator, the HPA, only needs one thing from each gauge: a number saying how much action is needed.

i
Tip

If no built-in scaler fits your system, you have two options. You can use the Prometheus or generic metrics-API scalers to read a custom number, or you can write an external scaler, a small gRPC service that KEDA calls. Both are covered in Chapter 17.

8Authentication: Letting KEDA Read Your Event Sources

Most queues and databases need a password or identity. KEDA offers safe ways to provide them without putting secrets into scaling configuration.

The problem

To count messages in a private queue, KEDA must prove who it is. If you write the connection string straight into the ScaledObject, anyone who can read that object can read your secret. We want the credentials stored in one safe place and referenced by name.

TriggerAuthentication

A TriggerAuthentication is a separate KEDA object that describes how to log in. A trigger refers to it by name. The authentication object can pull values from several places:

  • Kubernetes Secrets. The simplest option. The object points at a key inside a Secret.
  • Environment variables of the target workload. KEDA reads values the workload already uses.
  • Secret stores such as HashiCorp Vault. Values are fetched from a central vault at runtime.
  • Cloud workload identity. KEDA uses an identity from the cloud provider, such as Microsoft Entra workload identity on Azure, IAM roles for service accounts on AWS, or workload identity on Google Cloud. No stored password exists at all.

Namespaced and cluster-wide versions

A TriggerAuthentication lives in one namespace and can be used only by ScaledObjects in that namespace. A ClusterTriggerAuthentication is cluster-wide and can be shared. Use the namespaced version by default. It limits the damage if one team misconfigures something.

Everyday Analogy

Instead of writing your door code on the delivery instructions, you give the courier a pass card from the building manager. The courier shows the card and gets in. Workload identity is the pass card. A stored password is the code written on the note, which anyone who sees it can copy.

!
Security Warning

Prefer identity-based authentication wherever your cloud supports it. Passwords and keys can leak, be copied, or expire at awkward times. An identity that is granted only the single permission to read queue length is far safer than a key that can also read and delete messages.

9Internal Working: Who Does What, and When

The heart of KEDA is a clever division of labor between two different scaling mechanisms. Understanding this split explains almost everything about how KEDA behaves.

Two halves of the scaling range

Scaling a workload really has two separate problems. The first is deciding whether the workload should run at all: is it at zero, or is it at one or more? The second is deciding how many copies to run once it is awake. KEDA solves them in different places.

  • Between zero and one: the KEDA operator decides. The HPA cannot handle zero, so KEDA does it directly by changing the replica count of your workload.
  • Between one and many: the Kubernetes HPA decides. KEDA creates an HPA for you, and the HPA asks KEDA’s metrics server for the numbers it needs.
sequenceDiagram
  autonumber
  participant S as Event Source
  participant O as KEDA Operator
  participant D as Deployment
  participant H as HPA
  participant M as KEDA Metrics Server
  loop every polling interval
    O->>S: How much work is waiting?
    S-->>O: Value and activity
  end
  alt Work found and replicas are zero
    O->>D: Scale from 0 to 1
  end
  loop every HPA sync period
    H->>M: Request external metric value
    M->>O: Get latest value
    O-->>M: Current value
    M-->>H: Metric value
    H->>D: Set replicas between 1 and max
  end
  alt No activity for the cooldown period
    O->>D: Scale from 1 to 0
  end
Figure 2: The two-part scaling loop of KEDA and the HPA

Step by step

1

You create a ScaledObject

The webhook validates it. The operator notices it, builds a scaler for each trigger, and creates an HPA named after the ScaledObject.

2

The operator polls

Every polling interval it asks each scaler for a value and an activity flag, and keeps the latest answers in memory.

3

Activation

If at least one trigger is active and the workload is at zero, the operator sets the replica count to one. This is the wake-up call.

4

The HPA takes over

With one or more Pods running, the HPA asks the metrics server for the current value and computes how many Pods are needed.

5

Deactivation

When every trigger reports no activity, a timer starts. If the cooldown period ends without new activity, the operator scales the workload to zero.

Everyday Analogy

Think of a night-shift pizza shop. The owner, KEDA’s operator, decides whether to open the doors at all by watching the phone for the first order. Once the shop is open, the shift supervisor, the HPA, decides how many cooks are needed based on the number of tickets. When no tickets come for a long time, the owner locks up again.

i
Key Idea

Two clocks are always running: the operator’s polling interval, which defaults to 30 seconds, and the HPA’s sync period, which defaults to about 15 seconds. Total reaction time is the sum of these delays plus Pod startup. Chapter 21 shows how to shorten it.

10Scaling to Zero and the Idea of Activation

Going to zero is the most talked-about KEDA feature. It saves money, but it also changes how your system behaves, so it deserves a careful look.

Why zero matters

A workload with a minimum of one Pod costs money all day, even when nothing happens. If you have 200 small worker services and each sits idle 90 percent of the time, you pay for 200 always-on Pods to do almost nothing. With scale to zero, idle services use no CPU and no memory, and the cluster can shrink to fewer machines, which is where real savings appear.

Activation versus target

Each trigger in KEDA answers two different questions, and each question has its own threshold:

Question 1

Should the workload be awake?

This uses the activation value. If the measured number is above it, the trigger is active and the operator wakes the workload. If it is at or below, the trigger is inactive.

Question 2

How many copies are needed?

This uses the target value. Once the HPA is in charge, it divides the measured number by the target to decide the Pod count.

By default the activation value is zero, which means “wake up when there is any work at all.” You can raise it to avoid waking the workload for a trivial amount of work. For example, if starting the workload is expensive, you might say “do not wake unless at least 50 messages are waiting.”

The cooldown period

When the work disappears, KEDA does not shut down at once. It waits for the cooldown period, 300 seconds by default, with all triggers inactive before going from one to zero. This prevents a cycle of waking and sleeping if messages arrive in short bursts. Note that the cooldown applies only to the last step down to zero. Scaling from ten Pods to three is controlled by the HPA’s own rules.

The cost of sleeping: cold starts

When a workload is at zero and the first message arrives, someone must start a Pod, pull its image, start the program and make it ready. That can take from a few seconds to a few minutes. During that time the message simply waits in the queue. For background workers this is perfectly fine. For anything a person is waiting for, such as a web page, a cold start may be too slow. This is why scale to zero shines for queue and batch work, and why it needs extra care for interactive traffic (see the HTTP add-on in Chapter 17).

Benefits of zero

  • No compute cost while idle
  • Fewer nodes needed across many small services
  • Less noise and less clutter in the cluster
  • Good fit for queue-driven and scheduled work

Costs of zero

  • First request or message waits for a cold start
  • Caches and connections are lost on each sleep
  • Monitoring has nothing to scrape while it sleeps
  • Needs care with startup time and image size
!
Common Trap

If your minimum replica count is set above zero, KEDA never scales to zero, and the activation value only matters for edge cases. Teams sometimes set a minimum of one to be “safe” and then wonder why their bill did not drop. Decide on purpose.

11The Scaling Math Made Simple

You do not need advanced mathematics to predict what KEDA will do. One short idea explains nearly every scaling decision.

The basic rule

For queue-like triggers, the HPA uses an “average value per Pod” idea. It divides the total metric value by the target value per Pod, and rounds up. If 230 messages are waiting and your target is 10 messages per Pod, then 230 divided by 10 is 23 Pods. If 231 messages are waiting, the result is 23.1, which rounds up to 24 Pods. Rounding up means the system always leans toward having enough capacity.

Then the limits apply

After the calculation, the result is held between your minimum and maximum. If the math says 300 Pods and your maximum is 40, you get 40. If the math says 0 and your minimum is 2, you get 2. Remember that if the minimum is zero, the HPA itself works from one upward, and the operator handles the last step to zero.

230
messages waiting in the queue
10
target messages per Pod
23
Pods the math asks for (230 divided by 10)

The tolerance band

The HPA does not react to tiny changes. By default, if the ratio between the measured value and the target is within about 10 percent of one, it does nothing. This prevents constant small adjustments. With 23 Pods running and a queue that grows slightly, you may not see a change until the number moves enough to cross this band.

Choosing a good target value

The target is the most important number you pick. Ask yourself: how many messages can one Pod finish in a reasonable time? If one Pod handles 5 messages per second and you want the queue cleared within 20 seconds, one Pod can clear about 100 messages in that time, so a target near 100 messages per Pod would keep the queue short. If your messages are slow and heavy, the target might be 5. Measure first, then set the target, and check it under real load.

Everyday Analogy

If each cashier can handle ten customers during your target waiting time and 230 customers are in line, you need 23 cashiers. If there are 231, you need a 24th, because you cannot hire two-tenths of a cashier. The tolerance band is the manager deciding not to call in a new cashier for just one or two extra customers.

i
Good to Know

For metrics that are rates or percentages rather than counts, such as requests per second from Prometheus, the same idea holds. The total is compared with the target per Pod. The difference between “average value” and “plain value” metric types can change the math, so check which type your trigger uses.

12ScaledJob: One Job per Unit of Work

Sometimes the right answer is not “more copies of a long-running program” but “one short-lived task for each piece of work.” KEDA has a second main object for exactly that.

Deployments versus Jobs

A Deployment runs Pods that live until they are told to stop. A Kubernetes Job runs a Pod to completion and then lets it exit. Which is better for event-driven work? It depends on how long each task runs and how safe it is to interrupt.

QuestionScaledObject with a DeploymentScaledJob
What runs?Long-lived worker Pods that pull many messagesA new Job per batch of events, which ends when finished
Typical task lengthMilliseconds to a few minutesMinutes to hours
What happens on scale-down?Pods are terminated, perhaps in the middle of workRunning Jobs are never killed by scaling; they finish
Best forSteady stream of small messagesHeavy tasks such as video conversion, machine learning, reports

How a ScaledJob works

A ScaledJob looks similar to a ScaledObject but, instead of a scale target, it holds a template for the Job to create. KEDA polls the triggers on each polling interval. If it finds work, it creates Jobs, never more than the maximum replica count you set. Each Job runs its Pod to completion, and finished Jobs are kept for a while according to history limits so you can read their logs, and then cleaned up.

Scaling strategies

One subtle question is how many new Jobs to start when some are already running. KEDA offers several strategies:

Default

Subtract running Jobs

Starts enough new Jobs to cover the queue length minus the Jobs already running. Simple, and fine for most cases.

Accurate

Count in-flight messages

Takes into account that running Jobs have already claimed messages, so the queue length alone is misleading. Good with queues where messages become invisible while being processed.

Custom

Your own formula

Lets you tune the calculation with a multiplier and an offset when the defaults do not match your workload.

Eager

Use all free slots

Starts as many Jobs as there is room for, so that a large backlog is attacked as fast as the limits allow.

Use Case: Video transcoding at a media company

Each uploaded video must be converted into several formats. A conversion takes between 5 and 40 minutes and must never be interrupted halfway. The team uses a ScaledJob triggered by the upload queue. Each Job takes one video, converts it and exits. Peak hours create dozens of Jobs at once, and quiet hours create none, so there are no idle converters.

i
Tip

If your work items are long and not safe to interrupt, a ScaledJob is the right tool. If they are short and your program can finish its current message when told to shut down, a ScaledObject with a Deployment is simpler and starts work faster, since the Pods are already warm.

13Data Flow and Lifecycle of a Scaling Event

Let us follow one burst of work from the moment it arrives until the system returns to rest. This ties together everything you have learned so far.

flowchart LR
  A["Burst of messages arrives"] --> B["Queue length rises"]
  B --> C["Operator polls and sees activity"]
  C --> D{"Replicas at zero?"}
  D -->|"yes"| E["Operator sets replicas to 1"]
  D -->|"no"| F["HPA already running"]
  E --> F
  F --> G["HPA requests metric from metrics server"]
  G --> H["Desired replicas computed"]
  H --> I["Deployment scaled up"]
  I --> J["New Pods start and pull messages"]
  J --> K["Queue drains"]
  K --> L["HPA scales down after stabilization window"]
  L --> M{"No activity for cooldown period?"}
  M -->|"yes"| N["Operator sets replicas to 0"]
  M -->|"no"| K
Figure 3: Lifecycle of one burst of events, from arrival to scale to zero

Where time is spent

StageTypical delayCan you shorten it?
Operator notices new workUp to one polling interval (30 seconds by default)Yes, by lowering the polling interval
HPA reads the new value and decidesUp to about 15 secondsRarely; it is a cluster-wide setting
Pod scheduled onto a nodeSeconds if room exists; minutes if a new node must startYes, with spare capacity or fast node provisioning
Image pulled and container startedSeconds to minutesYes, with small images and cached layers
Application warm-upDepends on the programYes, with faster startup and readiness checks

Where state lives

KEDA keeps little state of its own. Your configuration lives in Kubernetes objects. The latest metric values live in the operator’s memory and are rebuilt after a restart. The HPA that KEDA creates is a normal Kubernetes object, so you can inspect it with ordinary tools. The status of each ScaledObject, including whether it is ready, active or in fallback, is written onto the object and visible through kubectl.

Everyday Analogy

Think of a fire brigade. The alarm rings (event), the dispatcher notices (polling), the trucks leave the station (Pod scheduling), they arrive and get to work (application warm-up), and when the fire is out they return and the station goes quiet (scale down). The time from alarm to first water is the sum of every stage, which is why fire stations invest in speeding up each one.

14Multiple Triggers, Schedules and Combining Signals

Real systems rarely depend on a single signal. KEDA lets you combine several, including time of day, in one object.

How several triggers combine

A ScaledObject can have many triggers. Each one independently proposes a Pod count. The HPA takes the highest of them. So if the queue trigger wants 8 Pods and the Prometheus trigger wants 12, you get 12. For activation, a workload wakes from zero if any single trigger is active, and goes back to sleep only when all are inactive. This “highest wins, any wakes it” behavior is safe by design: the system leans toward having enough capacity.

The cron scaler: scheduled capacity

The cron scaler turns the clock into a trigger. You give it a time zone, a start time, an end time and a desired number of Pods. Between the start and end, KEDA holds at least that many Pods. Outside the window, the cron trigger is inactive. This is perfect for predictable patterns: more capacity before the 9 a.m. rush, less overnight, and a bump before a weekly batch.

Use Case: Pre-warming before a sale

An online retailer knows its flash sale starts at noon every Friday. A cron trigger raises the minimum to 20 Pods at 11:50, so the app is warm when the first customers arrive. A queue trigger on the same ScaledObject handles anything beyond that. At 14:00 the cron window ends and the queue trigger alone controls the scale. The team gets both predictable readiness and flexibility for surprises.

Combining signals wisely

  • Queue plus cron. Scheduled floor, event-driven growth above it.
  • Queue plus CPU. Scale on backlog, with CPU as a safety valve if the work turns out heavier than expected.
  • Kafka lag plus Prometheus latency. Catch both a growing backlog and slow processing.
!
Common Trap

Using a CPU or memory trigger together with a scale-to-zero setup can confuse things. These triggers cannot work when no Pods exist, since there is nothing to measure. Pair them with an event-based trigger that can wake the workload, and treat CPU as a secondary signal.

15Fallback, Pausing and Custom Formulas

What happens when the thing KEDA depends on breaks? And how do you take manual control when you need it? These features answer both questions.

Fallback: a safe default when the source is down

Suppose KEDA cannot reach your message broker because of a network problem. Without a plan, it has no number, and the workload might stay stuck at whatever size it happened to have. The fallback feature lets you say: “if the scaler fails this many times in a row, hold the workload at this fixed number of Pods.” You pick the failure threshold and the replica count. When the source recovers, normal scaling resumes. The ScaledObject status shows a fallback condition while this is active, so monitoring can alert on it. Fallback works with metrics measured as an average per Pod, so check your trigger type.

Pausing autoscaling

Sometimes you want to freeze scaling, perhaps during a maintenance window, a debugging session or a data migration. KEDA supports annotations on the ScaledObject. One annotation pauses scaling and leaves the replica count where it is. Another pauses scaling and forces a specific number of replicas, which can even be zero. Removing the annotation resumes normal behavior. This is much safer than deleting the ScaledObject, since deletion hands control of the replica count back to whatever was there before.

Scaling modifiers: building your own formula

Newer versions of KEDA allow you to combine several triggers into one calculated value. Instead of “highest wins,” you write a small formula, for example a weighted sum of queue length and processing time. This is a power tool. It lets you express rules such as “scale on queue length, but only when error rate is low.” Because it is a newer feature, check the current KEDA documentation for its status and syntax before relying on it in production.

Safety

Fallback

Keeps a known-safe number of Pods when metrics cannot be read.

Control

Pause annotations

Freeze or pin the replica count without deleting anything.

Power

Scaling modifiers

Combine triggers with a formula when simple highest-wins is not enough.

Clarity

Status conditions

Ready, Active and Fallback flags tell you what KEDA thinks is happening.

Everyday Analogy

Fallback is the “if the radio goes silent, keep the engine at cruising speed” rule on a ship. Pausing is the captain taking the wheel from the autopilot. Scaling modifiers are a custom rule for the autopilot itself, such as “slow down when it is both foggy and busy.”

16Tuning Scale-Up and Scale-Down Behavior

Autoscaling that reacts too fast flaps up and down. Autoscaling that reacts too slowly causes backlogs. This chapter shows the dials that control the speed.

The HPA behavior settings

Because KEDA uses a real HPA, you can tune the HPA’s behavior through the ScaledObject’s advanced options. Two directions can be tuned separately:

  • Scale up. By default, the HPA may double the number of Pods, or add four, whichever is larger, every 15 seconds. That is fast. You can slow it down to protect a database from a sudden surge in connections.
  • Scale down. By default, the HPA looks back over the past five minutes and picks the highest recommendation before shrinking. This stabilization window prevents sudden drops after a short lull. You can lengthen it for spiky workloads, or shorten it to save money faster.
DialEffect of raising itEffect of lowering it
Polling intervalFewer calls to the event source, slower reactionFaster reaction, more load on the source, higher API cost
Cooldown periodLonger before scale to zero, fewer cold startsQuicker savings, more cold starts
Scale-down stabilizationSteadier, avoids flappingQuicker savings, risk of thrash
Scale-up rate limitGentler on downstream systemsFaster recovery from backlog
Target value per PodFewer Pods, longer queuesMore Pods, shorter queues, higher cost

Graceful shutdown: do not lose work when scaling down

When the HPA removes a Pod, Kubernetes sends it a polite stop signal and waits for a grace period before forcing it to stop. A well-written worker catches the signal, finishes its current message, and exits. A poorly written one is cut off mid-task, and the message is either lost or processed twice. For queue workers, set the grace period long enough to finish one typical message, and make sure your program handles the signal. Also design handlers to be idempotent, meaning that running the same message twice does no harm.

Everyday Analogy

Scaling down is like closing extra checkout lanes in a supermarket. A good store lets the cashier finish serving the customer at the till before closing the lane. A bad one switches off the till while the customer is paying. Graceful shutdown is the polite way to close a lane.

i
Tip

Tune with data, not guesses. Replay a realistic burst in a test environment, plot queue length and Pod count together, and adjust one dial at a time. The perfect settings for a bursty image-processing worker are rarely the right settings for a steady billing worker.

17Going Further: External Scalers, the HTTP Add-on and Custom Resources

The built-in scalers cover a great deal, but not everything. These extension points let KEDA reach almost any signal, including web traffic.

External scalers: write your own

If your system is unusual, for example an in-house job scheduler, you can write an external scaler. This is a small server that speaks a simple protocol over gRPC, a fast way for programs to call each other. KEDA calls it with questions such as “is there any work?” and “what is the current metric value?” The scaler can be written in any language, run anywhere inside or outside the cluster, and answers from any data source you like. There are two styles. In the pull style, KEDA asks on each polling interval. In the push style, the scaler keeps a connection open and tells KEDA the moment activity changes, which reacts faster for waking from zero.

The metrics-API and Prometheus scalers

Often you do not need new code at all. The Prometheus scaler lets you write a query against your monitoring system and scale on its result. This is how you scale on things like “orders per minute” or “99th percentile latency” with no extra programming. The metrics-API scaler does the same for any HTTP endpoint that returns a number in JSON. Together they cover a huge range of business signals.

The HTTP add-on: scaling web traffic, even to zero

Plain KEDA reacts to queues and metrics, not to individual web requests. For web applications there is a companion project, the KEDA HTTP add-on. It places a small proxy called an interceptor in front of your service. When a request arrives for an application that is asleep, the interceptor holds the request, tells KEDA to wake the application, and forwards the request when the first Pod is ready. The user sees a slow first response instead of an error. While running, the interceptor also counts requests, so scaling can follow real traffic. Check the project’s current maturity level before using it for critical user-facing paths, since the add-on has been developing more slowly than the core.

Scaling custom resources

KEDA can scale anything that supports the standard scale interface, not only Deployments. This includes StatefulSets and many custom resources created by operators, such as certain machine learning serving frameworks. As long as the object exposes how many replicas it wants, KEDA can drive it.

Extend

External scaler

Your own gRPC server for unusual event sources, in any language.

Reuse

Prometheus scaler

Turn any monitoring query into a scaling signal.

Generic

Metrics API scaler

Read a number from any HTTP endpoint returning JSON.

Web

HTTP add-on

Hold and forward requests so web apps can scale from zero.

Everyday Analogy

The built-in scalers are the standard sockets on the wall. An external scaler is a travel adapter you build for a strange plug. The HTTP add-on is a receptionist who greets a visitor at a closed office, quickly calls the staff in, and then shows the visitor through when the lights are on.

18Installing KEDA and Running It on Cloud Platforms

KEDA is easy to install, and several platforms ship it ready to use.

Ways to install

  • Helm chart. The most common method. One command installs the operator, the metrics server and the webhooks into their own namespace, and lets you set options through a values file.
  • Plain manifests. The project publishes ready-made files you can apply directly, which suits teams that prefer fully explicit configuration.
  • OperatorHub. On platforms that use operator catalogs, KEDA can be installed and upgraded through the catalog.
  • Managed add-ons. Some cloud services offer KEDA as a built-in feature you switch on.

KEDA on major platforms

PlatformHow KEDA appears
Azure Kubernetes ServiceA managed KEDA add-on that the cloud keeps up to date, and which works naturally with Azure workload identity.
Azure Container AppsScale rules in this serverless container service are built on KEDA, so the same concepts and scaler names apply.
Red Hat OpenShiftSupported as the Custom Metrics Autoscaler operator, a productized distribution of KEDA.
Amazon EKS and Google GKEInstalled through Helm or manifests. Identity features of each cloud let KEDA read queues and metrics without stored passwords.
Self-managed or on-premises clustersWorks anywhere. Use Secrets or a vault for credentials.

What to decide before installing

  • One KEDA per cluster. Only one metrics server can register the external-metrics interface in a cluster. If another adapter already owns it, you must resolve the conflict first.
  • Watch scope. By default KEDA watches all namespaces. You can limit it to chosen namespaces in shared clusters.
  • Resource requests. Give the operator enough memory for the number of ScaledObjects you plan to run.
  • Node placement. Place KEDA on reliable nodes, not on spot machines that may disappear.
!
Common Trap

Other tools can also claim the external-metrics interface, including some monitoring adapters. If two programs try to register it, one of them fails silently and the HPA reports missing metrics. When installing KEDA on a cluster that already uses an adapter, check how both can coexist.

19Security: Least Privilege for an Autoscaler

KEDA can change how many Pods run and it holds the keys to your queues. That makes it a sensitive component, and it deserves careful protection.

What KEDA is allowed to do

To work, the operator needs permission to read ScaledObjects, to read and change the scale of target workloads, to create and update HPAs, and to read the Secrets that TriggerAuthentications reference. These permissions are broad by default. Anyone who controls KEDA can start or stop your workloads, and may be able to read credentials that scalers use.

Protecting the system

  • Control who can create KEDA objects. Anyone who can create a ScaledObject can set the maximum replica count and cause a large bill or overload a downstream database. Use RBAC to limit these rights to trusted teams.
  • Prefer identity over passwords. Use cloud workload identity so no secrets are stored, and grant only the narrowest permission, such as reading queue attributes.
  • Use namespaced authentication. TriggerAuthentication objects stay inside their namespace. Use the cluster-wide kind only for shared credentials that you truly want every team to use.
  • Limit the watch scope. In multi-tenant clusters, restrict the operator to namespaces that need it, or run separate controlled setups.
  • Secure the metrics endpoint. The metrics server speaks through the Kubernetes aggregation layer. Keep its certificates valid and its network paths restricted.
  • Apply network policies. Allow the operator to talk only to the API server and to the event sources it needs.
  • Guard the supply chain. Install official images, pin versions and verify signatures where the project provides them.
  • Cap the blast radius. Use admission rules, for example with a policy engine, to enforce a maximum replica count and require a reasonable polling interval across all ScaledObjects.
ANTI-PATTERN 01Avoid
What people do

They put a full-access cloud key into a single shared cluster-wide authentication object and let every team use it.

Why it hurts

One leaked key now opens every queue in the account, and any team can accidentally read or drain another team’s queue.

Better approach

Give each team its own identity with read-only access to just its queue attributes, referenced from a namespaced authentication object.

Everyday Analogy

Giving KEDA broad credentials is like giving a building’s night manager a master key to every office. He needs to switch the lights on and off, not to read your filing cabinet. Narrow keys limit what a mistake or a thief can do.

20Monitoring, Logging and Metrics

An autoscaler you cannot see is an autoscaler you cannot trust. KEDA gives you status, events, logs and metrics.

Status on the objects

Start with the ScaledObject itself. Its status shows conditions: whether it is ready, whether it is active, and whether fallback is in effect. It also shows the name of the HPA it created, the external metrics it provides and the time of the last activity. A quick description of the object, plus a look at the HPA, answers most “why did it scale?” questions.

Events and logs

KEDA records Kubernetes events when it activates or deactivates a workload and when something fails, for example when a scaler cannot connect. The operator and metrics server also write structured logs. When scaling seems stuck, the operator log usually names the scaler and the exact error, such as a rejected credential or an unreachable broker.

Prometheus metrics

KEDA exposes its own metrics in the Prometheus format. Exact names change between versions, so check the documentation for yours, but the useful families are:

Value

Scaler metric value

The number each scaler last reported, such as queue length. Chart this next to Pod count.

Activity

Scaler active flag

Whether each trigger currently says there is work. Shows why a workload woke or slept.

Errors

Scaler and object errors

Counters of failed polls. A rise points to credential, network or source problems.

Latency

Scaler latency

How long the event source takes to answer. Slow answers delay scaling.

Dashboards and alerts

A single dashboard per workload that shows queue length, desired replicas, actual replicas, and processing time tells the whole story. Useful alerts include:

  • A scaler reporting errors for several polls in a row.
  • A workload in fallback mode.
  • Queue length rising while replica count is at its maximum, meaning you have hit your ceiling.
  • Queue length high but replicas at zero, meaning activation failed.
  • Operator or metrics server Pods restarting.
  • Oldest message age passing a service goal, which is often a better signal than length.
Everyday Analogy

A hospital shows each patient’s chart at the bedside, with trend lines, not only the latest number. Your dashboard should show the queue and the Pod count as two lines on the same chart. When the queue climbs and the Pod line does not follow, you see the problem immediately.

21Performance and Scalability

KEDA must itself scale gracefully, and it must scale your workloads fast enough. Both questions come down to a few measurable things.

30 s
default polling interval for each trigger
300 s
default cooldown before scaling to zero
100
default maximum replicas for a ScaledObject

Reaction time: how quickly can you scale?

Total time from burst to capacity is the sum of polling delay, HPA delay, Pod scheduling, image pull and application warm-up. Shortening the polling interval to a few seconds helps, but each poll is a call to your event source. Calls to cloud queue services may cost money and are subject to rate limits, so a very short interval across hundreds of ScaledObjects can add up. Balance speed against cost and limits.

Pod startup is usually the bottleneck

Teams often tune the polling interval and forget that a Pod takes 90 seconds to start. Make start-up faster by keeping images small, using cached base layers, avoiding heavy work at start, and defining readiness checks that turn true as soon as the program can really accept work. If new Pods cannot be placed because the cluster is full, the node autoscaler must add machines, which can take minutes. Keep a small buffer of spare capacity for latency-sensitive workloads.

Scaling KEDA with the number of objects

  • Many ScaledObjects. Each one has its own polling loop. Thousands are possible, but give the operator enough CPU and memory, and watch its logs for slow scalers.
  • Slow event sources. One scaler that takes ten seconds to answer can delay others sharing its loop. Watch scaler latency.
  • Shared queues. If twenty ScaledObjects poll the same broker, consider the total request rate that broker sees.
  • Metrics server load. The HPA asks for metrics every few seconds for each ScaledObject, and the metrics server answers from cached values, so this is cheap, but it must stay healthy.

Protecting what sits behind the workers

The fastest autoscaling is not always the best. If 200 Pods wake up and all open connections to the same database, the database may fall over. Set the maximum replica count to what downstream systems can bear, limit how fast scale-up can happen, and use connection pooling.

Everyday Analogy

Opening fifty extra checkout lanes does not help if there is only one door out of the store. The bottleneck simply moves. Before you speed up scaling, find what the extra workers will push against next.

i
Tip

Measure the time from “message enqueued” to “message processed” at the 95th and 99th percentile. That single number captures every delay from queue to worker and tells you if your scaling settings are good enough for your business goal.

22High Availability and Reliability

KEDA is on the path of your scaling, so you must know what happens when it stumbles and how to make it sturdy.

What breaks when KEDA is down

If the operator stops, workloads that are already running keep running at their current size. The HPA that KEDA created still exists, but it cannot get fresh metrics, so it holds steady or reports missing metrics. Scaling to and from zero stops, which is the more serious effect: a sleeping workload will not wake up while the operator is down, and messages wait in the queue. Because queues hold messages safely, the usual result is delay, not data loss. That makes event-driven systems naturally forgiving, provided the queue itself is durable.

Making KEDA itself highly available

  • Run standby operator replicas. The operator supports leader election, so extra replicas wait in standby and take over quickly if the active one fails. Check the current documentation for how the metrics server should be replicated.
  • Spread across zones. Use topology spread or anti-affinity so failure of one zone does not remove all KEDA Pods.
  • Set disruption budgets. Prevent node upgrades from evicting every KEDA Pod at once.
  • Use priority classes. Make sure KEDA is scheduled even when the cluster is under pressure.
  • Use fallback. Give important ScaledObjects a safe replica number for when their event source cannot be read.

Designing workloads that recover well

Make your consumers idempotent, so that a message delivered twice is not harmful. Use dead-letter queues so a poisonous message does not block a worker forever. Use visibility timeouts or acknowledgments properly, so messages from a worker that is shut down mid-task return to the queue. These habits turn scaling events from risky moments into routine ones.

Why KEDA failures are mild

  • Queues keep messages while workers are away
  • Running Pods are not stopped by a KEDA outage
  • Standby operators take over automatically
  • Fallback sets a safe size

Where it can still hurt

  • Sleeping workloads cannot wake while the operator is down
  • Latency-sensitive paths feel delays quickly
  • Bad credentials stop scaling silently unless alerted
  • A wrong maximum can overload other systems

23Cost Optimization and FinOps

For many teams, the main reason to adopt KEDA is money. Here is how the savings actually appear, and how to avoid false economies.

Where the savings come from

  • No idle Pods. Workloads at zero use no CPU or memory requests, so the scheduler can pack other work onto fewer machines.
  • Right-sized peaks. Instead of provisioning for the worst day all month, capacity follows demand hour by hour.
  • Fewer nodes. When the node autoscaler sees empty machines, it removes them. This is where the actual bill falls.
  • Cheaper machine types. Interruptible workers can run on discounted spot or preemptible machines, because a queue safely absorbs interruptions.

The savings only appear if nodes shrink

Scaling Pods to zero saves nothing by itself if the machines underneath stay on. The money is saved when the node autoscaler removes unused nodes. Make sure the node layer is set up to scale down, and watch for Pods that block it, such as ones with local storage or restrictive disruption budgets.

Counting the costs on the other side

CostWhere it shows upHow to manage it
Cold startsSlower first response after idle periodsLonger cooldown, smaller images, or a minimum of one for sensitive paths
Polling API callsCloud queue request charges and rate limitsReasonable polling interval, shared metrics, push-style scalers
Image pullsNetwork and registry costs for frequent restartsUse a nearby registry and cached layers
Runaway scalingA bug or poison messages create a huge Pod countA sensible maximum, alerts, dead-letter queues

Use Case: Cutting the cost of overnight batch workers

A data company ran 60 batch worker services around the clock, each with two Pods, though each did real work only for a couple of hours a day. After moving them to KEDA with scale to zero and a queue trigger, their daytime need fell to a fraction of the old total, and the node autoscaler removed over a third of the machines in the worker pool. The team kept one always-on Pod only for the two services whose users waited for responses.

i
Good to Know

Tag your ScaledObjects with team and cost-center labels, and export Pod-hours by workload. A report that shows “we saved this much last month” is the best way to keep support for the project.

24KEDA Compared with Other Approaches

KEDA is one of several ways to scale on demand. Knowing the alternatives helps you use each where it is strongest.

ApproachScales onScale to zeroBest for
Plain HPACPU, memory, and metrics from an adapter you installNo (by default)Request-driven services with steady CPU patterns
HPA with a custom metrics adapterAny metric the adapter exposesLimitedTeams who already run a single adapter for one source
KEDADozens of event sources, schedules and custom queriesYesQueue, stream, batch and scheduled workloads
Knative ServingIncoming HTTP request concurrency and rateYesServerless web services with revision-based routing
Custom controllerAnything you codeIf you build itHighly specialized needs, at the price of maintenance
Provider serverless functionsProvider eventsYesSmall stateless tasks when you accept lock-in

KEDA and Knative

The two projects solve different problems and can live side by side. Knative is a full serverless layer for web services: it routes traffic, manages revisions and scales mainly on request load. KEDA is a focused autoscaler for any workload and any event source, with no routing layer. Pick Knative when you want a serverless platform for HTTP services. Pick KEDA when you want to keep ordinary Deployments and Jobs and add event-driven scaling to them.

KEDA and node autoscalers

KEDA changes the number of Pods. A node autoscaler such as the Cluster Autoscaler or Karpenter changes the number of machines. They are partners: when KEDA asks for many new Pods and the cluster is full, Pods wait in a pending state, and the node autoscaler adds machines to fit them. A good design plans both layers together.

KEDA strengths

  • Graduated CNCF project with wide support
  • Huge catalog of scalers
  • Scale to zero for any workload
  • Uses the HPA and keeps familiar behavior
  • No application rewrite needed

KEDA trade-offs

  • One more component to run and secure
  • Cold starts when scaling from zero
  • Reaction time bounded by polling and Pod startup
  • Web traffic needs an additional add-on

25Design Patterns and Anti-Patterns

Teams that run KEDA well tend to follow the same habits. Teams that struggle tend to fall into the same traps.

Patterns that work

Pattern

Competing consumers

Many identical workers read from one queue. KEDA changes the number of workers, and the queue spreads the work.

Pattern

Queue-based load leveling

Let a queue absorb bursts so the slow downstream system sees a steady flow, with KEDA keeping the backlog short.

Pattern

Job per unit of work

Use ScaledJob for heavy, uninterruptible tasks so scale-down never kills work in progress.

Pattern

Scheduled floor, event ceiling

A cron trigger guarantees capacity at known busy times, and event triggers handle the unexpected.

Pattern

Dead-letter queue

Failed messages move aside after several attempts, so one bad message cannot keep the queue growing forever.

Pattern

Backpressure with a ceiling

The maximum replica count matches what the database or partner API can handle, so scaling never causes a second outage.

Patterns that hurt

ANTI-PATTERN 02Avoid
What people do

They leave the maximum replica count at the default of 100 for every worker “because KEDA will handle it.”

Why it hurts

A burst or a bug can create a hundred Pods that all hit the same database. The fix for the backlog becomes a second incident.

Better approach

Calculate the highest safe concurrency for downstream systems and set the maximum with a margin below it.

ANTI-PATTERN 03Avoid
What people do

They run an HPA and a ScaledObject against the same Deployment.

Why it hurts

Two controllers fight over the replica count. The number of Pods jumps up and down, and nobody can explain why.

Better approach

Delete the hand-made HPA. Put every trigger, including CPU if needed, into the ScaledObject.

ANTI-PATTERN 04Avoid
What people do

They scale long, uninterruptible tasks with a Deployment, then wonder why work is lost or repeated during scale-down.

Why it hurts

The HPA terminates Pods without knowing they are mid-task. Messages come back to the queue, and half-finished work is repeated or corrupted.

Better approach

Use ScaledJob, or make workers handle the stop signal and finish their current message with a long enough grace period.

ANTI-PATTERN 05Avoid
What people do

They scale on queue length alone while workers are quietly failing and returning messages to the queue.

Why it hurts

The queue stays long, so KEDA adds more failing Pods, and cost rises without any work being finished.

Better approach

Add a dead-letter queue, alert on error rates, and cap the maximum so a failure cannot turn into a runaway bill.

26Best Practices and Common Mistakes

A short checklist you can paste into your team’s playbook.

Do

  • Measure how much work one Pod can finish before setting the target value
  • Set a maximum that downstream systems can handle
  • Use identity-based authentication where possible
  • Handle the stop signal and finish the current message
  • Make consumers idempotent and add dead-letter queues
  • Alert on scaler errors, fallback mode and hitting the maximum
  • Keep ScaledObjects in Git, next to the workload they scale
  • Load-test with a realistic burst before going live

Do not

  • Create an HPA for a workload already managed by KEDA
  • Scale to zero for paths where a person waits on a cold start
  • Set a very short polling interval on rate-limited services
  • Share one powerful credential across all teams
  • Forget that the node layer must also scale down
  • Treat the queue as bottomless and ignore message age
  • Rely on CPU alone for workers that mostly wait
  • Leave experimental features in critical paths without testing

The most common mistakes, explained

  • Wrong target value. Setting the target to 1 message per Pod, “to be fast”, creates huge Pod counts for small backlogs. Set it by measured capacity.
  • Ignoring the activation value. A workload that wakes for every single message may start and stop constantly. Raise the activation value when starting is costly.
  • Forgetting that the cooldown only covers the last step. Scaling from many Pods to one is controlled by HPA behavior, not the cooldown period.
  • Using the wrong metric type. A value that is a total needs to be divided among Pods. A value already measured per Pod should not be. Mixing them gives wrong Pod counts.
  • Setting minimum replicas above zero by habit. This quietly removes the savings of scale to zero.
  • Trusting default timeouts for slow sources. A scaler that often times out causes erratic scaling. Fix the source or choose a different metric.
  • Not testing fallback. Teams configure it, but never block the source in a test to see what happens.
i
Tip

Keep a small “scaling contract” document per service: what the trigger is, why the target value was chosen, the maximum and the reason for it, and who to call. When the system behaves strangely at 3 a.m., this one page saves hours.

27Troubleshooting Guide

When scaling does not behave, work through these problems in order. Most issues fall into a handful of categories.

Problem: the workload does not scale at all

  • Check the ScaledObject status. Is it ready? An invalid trigger setting or an unreachable source shows up here first.
  • Check the operator log. Look for authentication errors, connection errors or messages that the target could not be found.
  • Check the HPA. Does the HPA exist, and does it report a current metric value? A missing value usually means the metrics server is not registered correctly.
  • Check the target. The name and kind in the ScaledObject must match the real workload in the same namespace.

Problem: it will not wake from zero

Confirm that the trigger really reports activity. Compare the measured number with the activation value. If the activation threshold is higher than the current backlog, the trigger is correctly inactive. Also check whether the pause annotation is present, and whether a minimum of zero is actually set.

Problem: it scales up but never down

Look at the stabilization window and the scale-down policies. A long window holds the highest recent recommendation. Check whether another trigger, such as a CPU trigger or a cron window, is keeping the number high. Look also for messages that are stuck in flight, which can make the queue appear non-empty.

Problem: the Pod count flaps up and down

Suspect a target value that is too sensitive, a polling interval shorter than the processing time, or two autoscalers competing for the same workload. Lengthen the stabilization window and confirm that there is only one HPA.

Problem: scaling is correct but still too slow

Measure each stage: polling delay, HPA delay, scheduling, image pull and warm-up. Most of the time the largest part is Pod and node startup, not KEDA. Reduce image size, keep spare node capacity, and shorten the polling interval where the source allows it.

Problem: errors about metrics not available

This normally means the external-metrics interface is not served properly. Check that the metrics server Pod is healthy, that its registration with the API server shows as available, and that no other adapter has claimed the same interface.

i
Good to Know

A quick mental model: three questions find most faults. Can KEDA read the source? Does the HPA see the number? Can the cluster place the new Pods? A “no” to any of them tells you which layer to fix.

28Real-World and Industry Examples

KEDA is not a niche tool. It sits underneath major cloud services and runs in many production clusters.

Microsoft: Azure Functions and Azure Container Apps

KEDA was created partly to let Azure Functions run on any Kubernetes cluster and still scale on events. Azure Container Apps, a serverless container service, uses KEDA for its scale rules, so its queue, stream and schedule rules map directly onto KEDA scalers. Azure Kubernetes Service also offers KEDA as a managed add-on.

Red Hat: OpenShift Custom Metrics Autoscaler

Red Hat co-founded KEDA and ships a supported distribution of it for OpenShift customers, called the Custom Metrics Autoscaler. Enterprises use it to scale workloads on Kafka lag and Prometheus metrics inside their regulated OpenShift environments.

E-commerce order processing

An online retailer places each order on a queue. Workers charge the card, reserve stock and send confirmation. During promotions the queue explodes, and KEDA grows the workers from a handful to several dozen within a couple of minutes. After the rush, the workers shrink back, and at night they scale to zero.

Streaming analytics

A company processes sensor and clickstream data from Kafka. Consumer lag is the signal. KEDA keeps one consumer per few partitions and grows consumers as lag grows, up to the number of partitions, since extra consumers beyond that would sit idle.

Machine learning inference and batch scoring

A data team runs scoring jobs when new data lands in storage. A ScaledJob starts one job per new batch, on GPU nodes that are only paid for while the jobs run. When no data arrives, no GPU costs accrue.

CI build runners

Engineering teams run self-hosted build agents. A scaler watches the number of pending builds in the CI system and creates agents on demand. Idle agents disappear, and developers wait less for builds during busy hours.

i
Pattern Across All of These

In every example there is a clear backlog signal, workers that can safely run in parallel, and a ceiling that protects downstream systems. The project also maintains a public list of end-user adopters if you want to see who else uses it.

The cheapest server is the one that is not running, and the best-served customer is the one whose work started the moment it arrived.

29Case Study: Moving a Payment Notification Platform to KEDA

This is an illustrative story built from common patterns. The company is fictional, but the decisions and problems are realistic.

The situation

PayWave is a payments company whose platform sends receipts, fraud alerts and settlement reports through a set of queue workers. There were 45 worker services, each running at least three Pods around the clock for safety. Traffic was heavily uneven: a monthly salary day created a rush 30 times higher than a quiet night. The team faced two problems. During salary day, queues grew faster than the old CPU-based scaling reacted, and customers received receipts up to 20 minutes late. During the rest of the month, most workers sat idle and cost money.

The approach

1

Measure capacity

The team benchmarked each worker to learn how many messages one Pod could finish in 30 seconds. These numbers became the target values.

2

Pilot with three services

They moved the receipt, alert and report workers first. Receipt workers kept a minimum of two Pods because customers expect fast receipts. Report workers went to zero.

3

Protect the database

Load testing showed the database failed at about 60 concurrent worker connections. The combined maximum across services was set below that, and a connection pool was added.

4

Add schedules

A cron trigger raised the receipt workers’ floor on salary days an hour before the expected rush.

5

Roll out and observe

The remaining services moved over four weeks, with dashboards showing queue age, Pod count and error rates side by side.

Problems they hit

The first salary day exposed a poison message that crashed workers and returned to the queue repeatedly. The queue never emptied, so KEDA kept scaling to the maximum. The cap held the damage, and an alert on the maximum being reached caught it within minutes. The team then added a dead-letter queue. Another issue was a cold start of nearly two minutes for report workers because of a large image. Slimming the image brought it under 20 seconds.

The results

20 min to 1 min
worst-case receipt delay on salary day
Over 60%
fewer worker Pod-hours in a typical month
2
services kept a minimum above zero by design
i
Lessons to Copy

Benchmark before choosing targets, protect downstream systems with a ceiling, use schedules for predictable peaks, add dead-letter queues, and keep a minimum for services where a person is waiting. Most of the value came from these ordinary habits, not from any clever setting.

30Migrating, Upgrading and Keeping KEDA Healthy

Adopting KEDA is a project, and so is keeping it current. These steps make both smooth.

Migrating from a plain HPA

1

Inventory

List the workloads that scale on CPU today but really depend on queues, streams or schedules. Those are the best candidates.

2

Translate

Choose the trigger that reflects real work, and set the target from measured capacity. Keep a CPU trigger as a safety valve if useful.

3

Switch over carefully

Remove the old HPA and create the ScaledObject in the same change, so the two never fight. Keep the replica count stable during the swap.

4

Watch and tune

Compare queue age and cost before and after. Adjust targets, polling and stabilization.

Upgrading KEDA

Treat each upgrade like any platform change. Read the release notes for changed defaults, deprecated settings and renamed metrics. Upgrade a test cluster first and replay a burst. Check that scalers you rely on have not changed behavior. Pin versions so no one gets a surprise upgrade. Confirm that your Kubernetes version is supported by the KEDA version you choose, since each release supports a range of Kubernetes versions.

Ongoing care

  • Review quarterly. Look at which workloads hit their maximum, which never scale, and which keep a high minimum without a reason.
  • Retire unused objects. Delete ScaledObjects for services that no longer exist.
  • Track deprecations. Scalers and settings are occasionally renamed or removed. Watch for warnings in logs.
  • Rehearse failure. Once in a while, block a source in a test environment and confirm that fallback and alerts behave as designed.
Everyday Analogy

An autoscaler is like the thermostat in a building: install it once and it quietly works, but someone still needs to check the settings each season, replace parts that wear out, and confirm that it behaves when the weather does something unusual.

31Frequently Asked Questions

Short answers to the questions people ask most often.

Q1What is KEDA in one sentence?
KEDA is a Kubernetes add-on that scales Pods based on events and external metrics, such as queue length, stream lag or schedules, including scaling down to zero and back up.
Q2Does KEDA replace the Horizontal Pod Autoscaler?
No. KEDA creates and feeds a regular HPA for scaling between one and many Pods, and handles the step between zero and one itself.
Q3Do I have to change my application code?
No. Your application keeps reading from its queue or stream as before. For safe scale-down, it should handle the stop signal and process messages idempotently, but those are good habits anyway.
Q4What is the difference between a ScaledObject and a ScaledJob?
A ScaledObject changes the number of Pods of a long-running workload. A ScaledJob creates a separate Kubernetes Job for units of work, so running tasks are never interrupted by scale-down.
Q5Can KEDA scale to zero?
Yes, when the minimum replica count is zero. The KEDA operator handles the transition between zero and one. The HPA handles everything above one.
Q6How fast does KEDA react?
The delay is the polling interval, plus the HPA sync period, plus Pod scheduling and startup. With defaults it is typically under a minute for the decision, plus however long your Pods take to start.
Q7What happens if the event source is unavailable?
Without fallback, scaling pauses with the last known state. With fallback configured, KEDA holds a safe number of replicas that you choose after a number of consecutive failures.
Q8Can I use more than one trigger?
Yes. Each trigger proposes a Pod count and the highest wins. The workload wakes from zero if any trigger is active.
Q9Is it safe to store credentials for KEDA?
It is safest to use cloud workload identity so no password exists. If you must use secrets, reference them through a TriggerAuthentication in the same namespace and give them minimal permissions.
Q10Can KEDA scale web applications?
Yes, through Prometheus-based request metrics, or through the HTTP add-on that holds requests while the application wakes up. A cold start still adds latency, so many teams keep a minimum of one for user-facing paths.
Q11What is the difference between activation and target values?
The activation value decides whether the workload should be running at all. The target value decides how many Pods to run once it is awake.
Q12Does scaling Pods to zero reduce my cloud bill?
Only when the node autoscaler also removes the machines that become empty. Without that, you free capacity inside the cluster but still pay for the machines.
Q13How many consumers should I allow for a Kafka topic?
Not more than the number of partitions, since extra consumers in the same group sit idle. Set the maximum replica count to the partition count or lower.
Q14Can I pause KEDA temporarily?
Yes. Annotations on the ScaledObject can pause scaling or pin the workload to a fixed replica count until you remove them.
Q15What if my messages take a long time to process?
Use a ScaledJob, or give workers a long enough termination grace period and make sure unacknowledged messages return to the queue when a Pod is stopped.
Q16Can KEDA scale resources other than Deployments?
Yes. Any resource that exposes the standard scale interface can be a target, including StatefulSets and many custom resources.
Q17How should I choose the polling interval?
Start with the default of 30 seconds and shorten it only if your business goal needs faster reaction and the event source can handle the extra requests. Many cloud queue services charge per request or limit how often you may ask, so a very short interval across hundreds of workloads can become expensive.
Q18Will KEDA lose messages when it scales a workload down?
KEDA itself does not touch messages. Safety depends on your workers and your queue. If a Pod is stopped before it acknowledges a message, a well-configured queue returns that message for another worker to take. This is why graceful shutdown and idempotent handlers matter.
Q19Can several teams share one KEDA installation?
Yes. KEDA is installed once per cluster and each team creates objects in its own namespace. Use RBAC to control who may create scaling objects, namespaced authentication to separate credentials, and policy rules to cap maximum replicas and polling intervals.
Q20How do I test a scaling setup before production?
Build a test environment with a copy of the queue, then publish a realistic burst of messages. Chart queue length, desired and actual Pods, and processing time together. Repeat with a broken credential to confirm that alerts and fallback behave as designed, and with a poison message to confirm the maximum protects you.

32Summary and Key Takeaways

If you remember only a handful of ideas from this guide, make them these.

Key Takeaways

  • Scale on the work waiting, not on how hot the kitchen looks. For queues, streams and schedules, backlog signals predict demand far better than CPU.
  • KEDA extends the HPA, it does not replace it. The operator handles zero to one, and a real HPA handles one to many through KEDA’s metrics server.
  • One object tells the story. A ScaledObject names the target, the limits, and the triggers. A ScaledJob creates a Job per unit of work for long tasks.
  • Activation and target are different ideas. One decides whether to be awake, and the other decides how many copies to run.
  • Protect what sits behind the workers. Pick a maximum that downstream databases and partners can handle, and cap scaling speed if needed.
  • Secure the autoscaler. Use workload identity, namespaced authentication, narrow permissions and policy limits on who may create scaling objects.
  • Measure, then tune. Watch queue age, scaler errors, fallback and Pod counts together. Benchmark capacity to choose targets, and remember that Pod and node startup are often the slowest steps.