> For the complete documentation index, see [llms.txt](https://docs.release.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.release.com/reference-documentation/reference-examples/event-driven-autoscaling-with-keda.md).

# Event-driven autoscaling with KEDA

Autoscale services on external events with KEDA

Release supports [KEDA](https://keda.sh/) (Kubernetes Event-Driven Autoscaling) so your services can scale on external signals — not just CPU and memory. Where the built-in [`autoscale`](/reference-documentation/application-settings/application-template/schema-definition.md#autoscale) configuration uses the Horizontal Pod Autoscaler (CPU/memory only), KEDA can scale a service on a message queue's depth, a Kafka topic's consumer lag, a Prometheus query, a cron schedule, and [dozens of other scalers](https://keda.sh/docs/latest/scalers/) — including scaling all the way down to zero.

You declare autoscaling once in your [Application Template](/reference-documentation/application-settings/application-template.md) with a `scaled_object` block on a service. Release renders a KEDA `ScaledObject` into every environment's namespace automatically — so you don't have to `kubectl apply` one resource per environment.

## Prerequisites

Two things must be in place before `scaled_object` works:

1. **KEDA installed on the cluster.** The KEDA operator (and its CRDs) must be installed on the cluster your environments deploy to. Release manages this as a cluster add-on and selects a KEDA version compatible with your cluster's Kubernetes version. **Contact Release to have KEDA installed on your cluster.**
2. **The feature enabled for your account.** `scaled_object` is gated per account. **Contact Release to enable it.**

If either is missing, Release rejects a configuration that uses `scaled_object` at validation time with a clear message — for example, `KEDA is not installed on this cluster — install the KEDA addon before using scaled_object`, or `scaled_object (KEDA autoscaling) is not enabled for this account`. No `ScaledObject` is applied until both prerequisites are satisfied.

{% hint style="info" %}
`scaled_object` is mutually exclusive with [`autoscale`](/reference-documentation/application-settings/application-template/schema-definition.md#autoscale) and `replicas` on the same service — KEDA owns the replica count, so setting more than one is a configuration error.
{% endhint %}

## Basic example

Add a `scaled_object` block to a service in your Application Template. This example scales a `worker` service between 1 and 10 replicas based on the consumer lag of a Kafka topic:

```yaml
services:
- name: worker
  image: "..."
  scaled_object:
    min_replica_count: 1
    max_replica_count: 10
    triggers:
    - type: kafka
      metadata:
        bootstrapServers: kafka.svc:9092
        consumerGroup: my-group
        topic: my-topic
        lagThreshold: '50'
```

On your next deploy, Release renders a KEDA `ScaledObject` targeting the `worker` deployment into the environment's namespace. KEDA then creates and manages a Horizontal Pod Autoscaler for you and scales `worker` as the Kafka lag rises and falls.

## Configuration

| Field               | Description                                                                                        |
| ------------------- | -------------------------------------------------------------------------------------------------- |
| `min_replica_count` | Minimum replicas (`>= 0`). Requires `max_replica_count` when set. Defaults to `0`.                 |
| `max_replica_count` | Maximum replicas (`> 0`, `>= min_replica_count`).                                                  |
| `polling_interval`  | How often KEDA checks the triggers, in seconds (`> 0`). Defaults to `30`.                          |
| `cooldown_period`   | Seconds to wait after the last active trigger before scaling back down (`> 0`). Defaults to `300`. |
| `triggers`          | One or more scaling triggers (at least one required).                                              |

Each trigger has:

| Field                | Description                                                                             |
| -------------------- | --------------------------------------------------------------------------------------- |
| `type`               | The KEDA scaler, e.g. `cpu`, `memory`, `kafka`, `prometheus`, `cron`.                   |
| `metadata`           | Scaler-specific settings, passed through to KEDA unchanged.                             |
| `metric_type`        | `Utilization`, `AverageValue`, or `Value`. Required for `cpu`/`memory` triggers.        |
| `authentication_ref` | Optional `{ name: <name> }` reference to a KEDA `TriggerAuthentication` on the cluster. |

The `metadata` for each trigger is **opaque** — Release passes it to KEDA verbatim. Consult the [KEDA scaler documentation](https://keda.sh/docs/latest/scalers/) for the exact `metadata` keys each scaler expects; you can use any KEDA scaler without waiting on a Release change.

## Scaling on CPU or memory

CPU and memory are also available as KEDA triggers. They are "resource" scalers and require `metric_type` (KEDA 2.18 and later require it as a trigger-level field):

```yaml
services:
- name: web
  image: "..."
  scaled_object:
    min_replica_count: 1
    max_replica_count: 5
    triggers:
    - type: cpu
      metric_type: Utilization
      metadata:
        value: '60'
```

{% hint style="info" %}
For plain CPU/memory autoscaling you can also use the simpler [`autoscale`](/reference-documentation/application-settings/application-template/schema-definition.md#autoscale) block, which uses the Horizontal Pod Autoscaler directly and needs no KEDA. Use `scaled_object` when you want event-driven triggers or scale-to-zero.
{% endhint %}

## Scale to zero on a schedule

A `cron` trigger scales a service up during a window and back down to `min_replica_count` (which can be `0`) outside it — for example, running a batch worker only during business hours:

```yaml
services:
- name: batch
  image: "..."
  scaled_object:
    min_replica_count: 0
    max_replica_count: 5
    triggers:
    - type: cron
      metadata:
        timezone: UTC
        start: 0 8 * * *
        end: 0 18 * * *
        desiredReplicas: '3'
```

## Triggers that need credentials

Some scalers (for example, a cloud queue or an authenticated Prometheus endpoint) need credentials. KEDA models these with a `TriggerAuthentication` object. Supply that object on the cluster, then reference it by name from your trigger:

```yaml
    triggers:
    - type: aws-sqs-queue
      metadata:
        queueURL: https://sqs.us-east-1.amazonaws.com/...
        queueLength: '5'
        awsRegion: us-east-1
      authentication_ref:
        name: my-sqs-auth
```

Release renders the reference (`authenticationRef`) on the `ScaledObject`; it does not create the `TriggerAuthentication` itself.

## Removing autoscaling

To stop autoscaling a service, remove its `scaled_object` block and deploy. Release deletes the `ScaledObject` it created for that service, and KEDA removes the Horizontal Pod Autoscaler it was managing. The service returns to its configured `replicas` (or the default of 1).

## Behavior across cluster upgrades

KEDA supports a moving window of Kubernetes versions. When your cluster is upgraded, Release automatically reconciles the KEDA add-on to a chart version compatible with the new Kubernetes version, so your `ScaledObject`s keep working. No action is required on your part.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.release.com/reference-documentation/reference-examples/event-driven-autoscaling-with-keda.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
