KEDA: event-driven autoscaling for Kubernetes workloads
KEDA is a Kubernetes-based Event Driven Autoscaling component. It provides event driven scale for any container running in Kubernetes
At a glance
- What is it?
- KEDA adds a metrics server and a ScaledObject custom resource on top of the Horizontal Pod Autoscaler so Kubernetes deployments can scale on queue depth, stream lag or any external event source, including down to zero replicas. This review covers how the mechanism works, how to install it, where it stops being the right tool, and how it differs from the plain HPA and from Karpenter.
- Who is it for?
- Adopt KEDA when your scaling signal lives outside the pod, in a queue, a stream or a database, and when idle-to-zero matters. Do not adopt it to replace the Horizontal Pod Autoscaler for CPU and memory driven scaling, and do not expect it to provision nodes: that is a different layer.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap KEDA fills between the HPA and real event sources
The Horizontal Pod Autoscaler is the built-in Kubernetes answer to scaling, and it works on one kind of input: resource metrics such as CPU and memory, plus custom or external metrics if something publishes them to the API. That is enough for request-driven web services. It is awkward for a worker that consumes a queue. A queue consumer can sit at 2 percent CPU while a backlog of a million messages grows, and the HPA will never react, because CPU is not the signal that matters.
KEDA exists to make the external signal the input. The README states that KEDA allows for fine-grained autoscaling, including to and from zero, for event driven Kubernetes workloads, and that it serves as a Kubernetes Metrics Server so users can define autoscaling rules with a dedicated custom resource definition. The two claims worth separating are the metric plumbing and the scale-to-zero. The first is plumbing that the HPA already supports in principle. The second is the part the HPA cannot do on its own, because an HPA with a target of zero replicas has nothing left to measure.
The audience is therefore narrow and specific: platform teams running queue consumers, stream processors, cron-like batch jobs, or any deployment whose load is visible in an external system rather than in its own container metrics. If your workload scales fine on CPU, KEDA adds a second control loop for no benefit.
How KEDA works: ScaledObject, metrics adapter and the HPA underneath
KEDA does not replace the HPA. It feeds it. The repository layout shows the split clearly: cmd/ holds the binaries, controllers/ holds the reconciliation logic, apis/ holds the custom resource types, pkg/ holds the scalers and the metrics adapter code, and schema/ holds the generated schemas. The Dockerfile builds the operator binary from these directories and runs it as a non-root distroless image, and the Makefile defines three separate images: keda, keda-metrics-apiserver and keda-admission-webhooks.
That three-image split is the architecture in miniature. The operator watches the custom resources and, for each one, creates and maintains an HPA. The metrics adapter implements the external metrics API so that the HPA has something to query. The webhook validates the custom resources before they reach the operator. When you declare a ScaledObject, the operator reads the trigger definitions inside it, the adapter polls the corresponding event source through the scaler implementation for that source, and the HPA scales the target deployment between the minimum and maximum you set. Scale-to-zero is handled by the operator rather than the HPA: when the trigger reports no work, the workload is taken out of the equation and the HPA is left alone.
The README notes that KEDA has no external dependencies and runs on both cloud and edge. That is a meaningful design constraint rather than a slogan: the adapter and operator are the only moving parts, so there is no message broker or metrics store to operate alongside them. The cost is that each scaler talks to its source directly, which is why the go.mod lists so many vendor SDKs, from Azure Service Bus and Event Hubs to ClickHouse and Google Cloud Spanner. Each scaler is a real client library with its own authentication model.
Deploying KEDA and defining a first ScaledObject
The README does not reproduce install commands. It states that there are many ways to deploy KEDA, including Helm, Operator Hub and YAML files, and links to keda.sh/docs/latest/deploy/ for the steps. The Artifact Hub badge in the README points at the keda chart, and the Makefile names the three images the deployment consists of: keda, keda-metrics-apiserver and keda-admission-webhooks. Follow the deploy page for the exact commands rather than inventing them.
What the repository does show is the shape of the custom resource you will write. The apis/ directory holds the CRD types, and the schema/ directory holds the generated schemas that the admission webhooks validate against. A ScaledObject names a target workload, a replica range and one or more triggers; the trigger type selects which scaler implementation in pkg/ reads the event source. The README's quickstart list is a good map of that shape: RabbitMQ with Go, Azure Functions with queues, Azure Functions with Kafka on OpenShift 4, and Azure Storage Queue with ScaledJob.
Two resources are worth distinguishing before you write anything. ScaledObject scales a long-running deployment, stateful set or custom resource, and it is the one that supports a minimum replica count of zero. ScaledJob creates Kubernetes Jobs per unit of work and targets run-to-completion processing, which is why the Azure Storage Queue quickstart uses it. Choosing the wrong one produces a configuration that applies cleanly but does not match how the workload behaves.
Where KEDA is the wrong tool
The clearest failure mode is treating KEDA as a general autoscaler. It is not one. It has no opinion about node capacity, so scaling a deployment from zero to fifty replicas can leave pods pending if the cluster has nowhere to put them. Karpenter and the cluster autoscaler operate one layer down, on nodes; KEDA operates on replicas. Running both is normal, but they solve different problems and neither substitutes for the other.
The second limitation is the scaler surface itself. Every event source needs a scaler implementation, and each one carries its own metadata keys, authentication mechanism and quirks. A source without a scaler cannot be used, and a source with a scaler that is marked experimental may change between releases. The go.mod dependency list is a reminder of how much third-party client code sits behind those triggers, and how much of it you inherit when you install the operator.
The third is scale-to-zero semantics. Zero replicas means no process to receive work. For an HTTP service this usually requires an intermediary that queues or buffers requests, and the README's own quickstart list reflects that shape: RabbitMQ with Go, Azure Functions with queues, Azure Storage Queue with a ScaledJob. If your workload must always answer immediately and has no queue in front of it, a minimum of zero is the wrong setting, and at that point KEDA is mostly a more expressive HPA rather than a different capability.
KEDA compared with the plain HPA and with Karpenter
Against the HPA, the difference is not the scaling algorithm but the source of the number. The HPA computes a desired replica count from metrics it can already read. KEDA adds an external metrics path and a custom resource that describes where the number comes from, and then hands the result to an HPA it manages. You can get external metrics into the HPA without KEDA by writing your own adapter, and teams with one unusual metric sometimes do. What you would be rebuilding is the trigger abstraction, the authentication handling per source, and the zero-replica handling. KEDA is worth it when you need more than one source or when you need to go to zero.
Against Karpenter, the comparison is a category error that shows up constantly in search results. Karpenter decides what nodes exist. KEDA decides how many pods run on them. A queue backlog can drive KEDA to request fifty replicas while Karpenter, or the cluster autoscaler, decides whether to add the machines to host them. If your problem is that pods are pending, KEDA is not the fix. If your problem is that pods exist but there are too few of them for the backlog, it is.
One more axis is where the operator runs. The README says KEDA can run on both the cloud and the edge, and that it integrates natively with Kubernetes components such as the Horizontal Pod Autoscaler with no external dependencies. That matters for clusters with restricted outbound connectivity: the scalers still need to reach their event sources, but there is no additional KEDA-operated service in the path.
Maintenance, release cadence and licence
The project is not archived and the last push to the default branch was on 2026-09-21. Recent releases are v2.20.0 on 2026-06-01, v2.20.1 on 2026-06-08 and v2.20.2 on 2026-07-31. That is a steady patch cadence on the 2.20 line, and the versioned module path in go.mod, github.com/kedacore/keda/v2, means major upgrades are expected to arrive as a new module path rather than in place.
Upgrade cost is dominated by two things. First, the CRD schemas: the repository ships a schema/ directory and the admission webhooks validate against it, so an upgrade can change what your existing ScaledObjects are allowed to contain. Second, the scaler implementations, which track upstream SDK versions. A scaler that depends on a vendor SDK with a breaking change will move with it, and the release notes are where that is recorded. The README does not document rollback, so plan the upgrade path yourself before applying it to a production cluster.
The licence is Apache-2.0, which permits commercial use, modification and redistribution with the usual conditions around notices and patent grant. KEDA is a CNCF graduated project, which means the project operates under foundation governance rather than a single vendor. None of that is legal advice; if you redistribute a modified build, read the licence text in the repository rather than a summary.
Editorial conclusion
Adopt KEDA when your scaling signal lives outside the pod, in a queue, a stream or a database, and when idle-to-zero matters. Do not adopt it to replace the Horizontal Pod Autoscaler for CPU and memory driven scaling, and do not expect it to provision nodes: that is a different layer. Before committing, check the scaler for your event source in the keda.sh scaler list, confirm your Kubernetes version against the compatibility notes, and verify the Helm chart values for the operator and metrics server in your cluster.
Frequently asked questions
What is KEDA used for?
KEDA provides event-driven autoscaling for workloads running in Kubernetes. It lets you define scaling rules against external event sources instead of only CPU and memory, and it can scale a workload down to zero replicas when there is no work.
What is the difference between the HPA and KEDA?
The Horizontal Pod Autoscaler is the built-in Kubernetes scaler and works from resource metrics. KEDA serves as a Kubernetes metrics server, exposes external event metrics to the HPA, and manages an HPA for each ScaledObject, adding scale-to-zero on top.
How do you pronounce KEDA?
The README does not address pronunciation, and the repository gives no guidance on it. The project name is written as KEDA throughout the documentation.
What is the latest version of KEDA?
The most recent release listed for the repository is v2.20.2, published on 2026-07-31, following v2.20.1 on 2026-06-08 and v2.20.0 on 2026-06-01.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kedacore-keda)