--- title: Scaling in Azure Container Apps description: Learn how applications scale in and out in Azure Container Apps. services: container-apps author: craigshoemaker ms.service: azure-container-apps ms.custom: devx-track-azurecli ms.topic: concept-article ms.date: 05/19/2026 ms.author: cshoe zone_pivot_groups: arm-azure-cli-portal-bicep --- # Set scaling rules in Azure Container Apps Azure Container Apps manages automatic horizontal scaling through a set of declarative scaling rules. As a container app revision scales out, the platform creates new instances of the revision on demand. These instances are known as replicas. To support this scaling behavior, Azure Container Apps uses KEDA (Kubernetes Event-driven Autoscaling). KEDA supports scaling against a variety of metrics like HTTP requests, queue messages, CPU and memory load, and event sources like Azure Service Bus, Azure Event Hubs, Apache Kafka, and Redis. For more information, see [Scalers in the KEDA documentation](https://keda.sh/docs/scalers/). When you add or edit scaling rules, you create a new revision of your container app. A revision is an immutable snapshot of your container app. To learn which types of changes trigger a new revision, see revision [change types](./revisions.md#change-types). [Event-driven Container Apps jobs](jobs.md#event-driven-jobs) use scaling rules to trigger executions based on events. ## Scale definition Scaling is the combination of limits, rules, and behavior. - **Limits** define the minimum and maximum possible number of replicas per revision as your container app scales. | Scale limit | Default value | Min value | Max value | |---|---|---|---| | Minimum number of replicas per revision | 0 | 0 | Maximum replicas configurable are 1,000. | | Maximum number of replicas per revision | 10 | 1 | Maximum replicas configurable are 1,000. | - **Rules** are the criteria used by Container Apps to decide when to add or remove replicas. [Scale rules](#scale-rules) are implemented as HTTP, TCP (Transmission Control Protocol), or custom. - **Behavior** is the combination of rules and limits to determine scale decisions over time. [Scale behavior](#scale-behavior) explains how scale decisions are made. As you define your scaling rules, consider the following items: - You aren't billed usage charges if your container app scales to zero. - Replicas that aren't processing but remain in memory might be billed at a lower "idle" rate. For more information, see [Billing](./billing.md). - If you want to ensure that an instance of your revision is always running, set the minimum number of replicas to 1 or higher. - During platform upgrades or maintenance, you might temporarily see more replicas than expected. Container Apps ensures your production workload isn't affected by pre-warming new replicas before shifting traffic, similar to default Kubernetes behavior. The extra replicas are removed automatically once the operation completes. ## Scale rules Three categories of triggers determine how scaling occurs: - [HTTP](#http): Based on the number of concurrent HTTP requests to your revision. - [TCP](#tcp): Based on the number of concurrent TCP connections to your revision. - [Custom](#custom): Based on custom metrics like: - CPU - Memory - Supported event-driven data sources: - Azure Service Bus - Azure Event Hubs - Apache Kafka - Redis If you define more than one scale rule, the container app begins to scale once the first condition of any rule is met. > [!NOTE] > If you're using [Functions on Container Apps](../container-apps/functions-overview.md), the default experience automatically configures scale rules based on function triggers and bindings. The Azure portal disables the **Add scale rules** button for these apps. If you need customer-defined rules, use `allowScalingRuleOverride` as described in [Override auto-generated KEDA scale rules for Azure Functions on Container Apps](functions-scale-rule-override.md). ## HTTP When you use an HTTP scaling rule, you control the threshold of concurrent HTTP requests that determines how your container app revision scales. Every 15 seconds, the number of concurrent requests is calculated as the number of requests in the past 15 seconds divided by 15. [Container Apps jobs](jobs.md) don't support HTTP scaling rules. In the following example, the revision scales out up to five replicas and can scale in to zero. The scaling property is set to 100 concurrent requests per second. ### Example ::: zone pivot="container-apps-bicep" The `http` section defines an HTTP scale rule. | Scale property | Description | Default value | Min value | Max value | |---|---|---|---|---| | `concurrentRequests`| When the number of HTTP requests exceeds this value, the app adds another replica. The app continues to add replicas up to the `maxReplicas` amount. | 10 | 1 | n/a | ```bicep resource symbolicname 'Microsoft.App/containerApps@2025-02-02-preview' = { ... properties: { ... template: { ... scale: { maxReplicas: 0 minReplicas: 5 rules: [ { name: 'http-rule' http: { metadata: { concurrentRequests: '100' } } } ] } } } } ``` > [!NOTE] > Set the `properties.configuration.activeRevisionsMode` property of the container app to `single` when using non-HTTP event scale rules. ::: zone-end ::: zone pivot="azure-resource-manager" The `http` section defines an HTTP scale rule. | Scale property | Description | Default value | Min value | Max value | |---|---|---|---|---| | `concurrentRequests`| When the number of HTTP requests exceeds this value, the app adds another replica. The app continues to add replicas up to the `maxReplicas` amount. | 10 | 1 | n/a | ```json { ... "resources": { ... "properties": { ... "template": { ... "scale": { "minReplicas": 0, "maxReplicas": 5, "rules": [{ "name": "http-rule", "http": { "metadata": { "concurrentRequests": "100" } } }] } } } } } ``` > [!NOTE] > Set the `properties.configuration.activeRevisionsMode` property of the container app to `single` when using non-HTTP event scale rules. ::: zone-end ::: zone pivot="azure-cli" Define an HTTP scale rule by using the `--scale-rule-http-concurrency` parameter in the [`create`](/cli/azure/containerapp#az-containerapp-create) or [`update`](/cli/azure/containerapp#az-containerapp-update) commands. | CLI parameter | Description | Default value | Min value | Max value | |---|---|---|---|---| | `--scale-rule-http-concurrency`| When the number of concurrent HTTP requests exceeds this value, the app adds another replica. The app continues to add replicas up to the `max-replicas` amount. | 10 | 1 | n/a | ```azurecli az containerapp create \ --name \ --resource-group \ --environment \ --image --min-replicas 0 \ --max-replicas 5 \ --scale-rule-name azure-http-rule \ --scale-rule-type http \ --scale-rule-http-concurrency 100 ``` ::: zone-end ::: zone pivot="azure-portal" 1. Go to your container app in the Azure portal. 1. Select **Scale**. 1. Select **Edit and deploy**. 1. Select the **Scale** tab. 1. Select the minimum and maximum replica range. :::image type="content" source="media/scale-app/azure-container-apps-scale-slide.png" alt-text="Screenshot of Azure Container Apps scale range slider."::: 1. Select **Add**. 1. In the *Rule name* box, enter a rule name. 1. From the *Type* dropdown, select **HTTP Scaling**. 1. In the *Concurrent requests* box, enter the number of concurrent requests you want for your container app. ::: zone-end ## TCP When you use a TCP scaling rule, you control the threshold of concurrent TCP connections that determines how your app scales. Every 15 seconds, the system calculates the number of concurrent connections as the number of connections in the past 15 seconds divided by 15. [Container Apps jobs](jobs.md) don't support TCP scaling rules. In the following example, the container app revision scales out to as many as five replicas and can scale in to zero. The scaling threshold is set to 100 concurrent connections per second. ### Example ::: zone pivot="container-apps-bicep" The `tcp` section defines a TCP scale rule. | Scale property | Description | Default value | Min value | Max value | |---|---|---|---|---| | `concurrentConnections`| When the number of concurrent TCP connections exceeds this value, the system adds another replica. The system keeps adding replicas up to the `maxReplicas` amount as the number of concurrent connections increases. | 10 | 1 | n/a | ```bicep resource symbolicname 'Microsoft.App/containerApps@2025-02-02-preview' = { ... properties: { ... template: { ... scale: { maxReplicas: 0 minReplicas: 5 rules: [ { name: 'tcp-rule' http: { metadata: { concurrentConnections: '100' } } } ] } } } } ``` ::: zone-end ::: zone pivot="azure-resource-manager" The `tcp` section defines a TCP scale rule. | Scale property | Description | Default value | Min value | Max value | |---|---|---|---|---| | `concurrentConnections`| When the number of concurrent TCP connections exceeds this value, the system adds another replica. The system keeps adding replicas up to the `maxReplicas` amount as the number of concurrent connections increases. | 10 | 1 | n/a | ```json { ... "resources": { ... "properties": { ... "template": { ... "scale": { "minReplicas": 0, "maxReplicas": 5, "rules": [{ "name": "tcp-rule", "tcp": { "metadata": { "concurrentConnections": "100" } } }] } } } } } ``` ::: zone-end ::: zone pivot="azure-cli" Define a TCP scale rule by using the `--scale-rule-tcp-concurrency` parameter in the [`create`](/cli/azure/containerapp#az-containerapp-create) or [`update`](/cli/azure/containerapp#az-containerapp-update) commands. | CLI parameter | Description | Default value | Min value | Max value | |---|---|---|---|---| | `--scale-rule-tcp-concurrency`| When the number of concurrent TCP connections exceeds this value, the system adds another replica. The system keeps adding replicas up to the `max-replicas` amount as the number of concurrent connections increase. | 10 | 1 | n/a | ```azurecli az containerapp create \ --name \ --resource-group \ --environment \ --image --min-replicas 0 \ --max-replicas 5 \ --transport tcp \ --ingress \ --target-port \ --scale-rule-name azure-tcp-rule \ --scale-rule-type tcp \ --scale-rule-tcp-concurrency 100 ``` ::: zone-end ::: zone pivot="azure-portal" The Azure portal doesn't support this feature. Use the [Azure CLI](scale-app.md?pivots=azure-cli#tcp), [Azure Resource Manager](scale-app.md?&pivots=azure-resource-manager#tcp), or [Bicep](scale-app.md?&pivots=container-apps-bicep#tcp) to configure a TCP scale rule. ::: zone-end ## Custom Create a custom Container Apps scaling rule based on any [ScaledObject](https://keda.sh/docs/latest/concepts/scaling-deployments/)-based [KEDA scaler](https://keda.sh/docs/latest/scalers/) by using these default values: | Default value | Seconds | |--|--| | Polling interval | 30 | | Cool down period | 300 | > [!NOTE] > The cool down period only takes effect when scaling in from the final replica to 0. The cool down period doesn't affect scaling as any other replicas are removed. For [event-driven Container Apps jobs](jobs.md#event-driven-jobs), create a custom scaling rule based on any [ScaledJob](https://keda.sh/docs/latest/concepts/scaling-jobs/)-based KEDA scalers. The following example demonstrates how to create a custom scale rule. ### Example This example shows how to convert an [Azure Service Bus scaler](https://keda.sh/docs/latest/scalers/azure-service-bus/) to a Container Apps scale rule, but you use the same process for any other [ScaledObject](https://keda.sh/docs/latest/concepts/scaling-deployments/)-based [KEDA scaler](https://keda.sh/docs/latest/scalers/) specification. For authentication, KEDA scaler authentication parameters take [Container Apps secrets](manage-secrets.md) or [managed identity](managed-identity.md#scale-rules). ::: zone pivot="container-apps-bicep" The following procedure shows you how to convert a KEDA scaler to a Container App scale rule. This snippet is an excerpt of a Bicep template to show you where each section fits in context of the overall template. ```bicep resource symbolicname 'Microsoft.App/containerApps@2025-02-02-preview' = { ... properties: { ... configuration: { ... secrets: [ { name: '' value: '' } ] } template: { ... scale: { maxReplicas: 0 minReplicas: 5 rules: [ { name: '' custom: { metadata: { ... } auth: [ { secretRef: '' triggerParameter: '' } ] } } ] } } } } ``` Refer to this excerpt for context on how the following examples fit in the Bicep template. First, define the type and metadata of the scale rule. 1. From the KEDA scaler specification, find the `type` value. ```yaml triggers: - type: azure-servicebus ⬅️ metadata: queueName: my-queue namespace: service-bus-namespace messageCount: "5" ``` 1. In the Bicep template, enter the scaler `type` value into the `custom.type` property of the scale rule. ```yml ... rules: [ { name: 'azure-servicebus-queue-rule' custom: { type: 'azure-servicebus' ⬅️ metadata: { queueName: 'my-queue' namespace: 'service-bus-namespace' messageCount: '5' } } } ] ... ``` 1. From the KEDA scaler specification, find the `metadata` values. ```yml triggers: - type: azure-servicebus metadata: queueName: my-queue ⬅️ namespace: service-bus-namespace ⬅️ messageCount: "5" ⬅️ ``` 1. In the Bicep template, add all metadata values to the `custom.metadata` section of the scale rule. ```yml ... rules: [ { name: 'azure-servicebus-queue-rule' custom: { type: 'azure-servicebus' metadata: { queueName: 'my-queue' ⬅️ namespace: 'service-bus-namespace' ⬅️ messageCount: '5' ⬅️ } } } ] ... ``` ### Authentication Container Apps scale rules support secrets-based authentication. Scale rules for Azure resources, including Azure Queue Storage, Azure Service Bus, and Azure Event Hubs, also support managed identity. Where possible, use managed identity authentication to avoid storing secrets within the app. #### Use secrets To use secrets for authentication, create a secret in the container app's `secrets` array. Use the secret value in the `auth` array of the scale rule. KEDA scalers can use secrets in a [TriggerAuthentication](https://keda.sh/docs/latest/concepts/authentication/) that the `authenticationRef` property references. You can map the TriggerAuthentication object to the Container Apps scale rule. 1. Find the `TriggerAuthentication` object referenced by the KEDA `ScaledObject` specification. 1. In the `TriggerAuthentication` object, find each `secretTargetRef` and its associated secret. ```yaml apiVersion: v1 kind: Secret metadata: name: my-secrets namespace: my-project type: Opaque data: connection-string-secret: ⬅️ --- apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: azure-servicebus-auth spec: secretTargetRef: - parameter: connection ⬅️ name: my-secrets ⬅️ key: connection-string-secret ⬅️ --- apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: azure-servicebus-queue-rule namespace: default spec: scaleTargetRef: name: my-scale-target triggers: - type: azure-servicebus metadata: queueName: my-queue namespace: service-bus-namespace messageCount: "5" authenticationRef: name: azure-servicebus-auth ``` 1. In the Bicep template, for each secret: 1. Add a [secret](./manage-secrets.md) to the container app's `secrets` array containing the secret name and value. 1. Add an entry to the `auth` array of the scale rule. 1. Set the value of the `triggerParameter` property to the value of the `secretTargetRef`'s `parameter` property. 1. Set the value of the `secretRef` property to the name of the `secretTargetRef`'s `key` property. ```bicep resource symbolicname 'Microsoft.App/containerApps@2025-02-02-preview' = { ... properties: { ... configuration: { ... secrets: [ { ⬅️ name: 'connection-string-secret' ⬅️ value: '' ⬅️ } ⬅️ ] } template: { ... scale: { maxReplicas: 0 minReplicas: 5 rules: [ { name: 'azure-servicebus-queue-rule' custom: { type: 'azure-servicebus' metadata: { queueName: 'my-queue' namespace: 'service-bus-namespace' messageCount: '5' } auth: [ { secretRef: 'connection-string-secret' triggerParameter: 'connection' } ] } } ] } } } } ``` Some scalers support metadata with the `FromEnv` suffix to reference a value in an environment variable. Container Apps looks at the first container listed in the ARM template for the environment variable. Refer to the [considerations section](#considerations) for more security related information. #### Using managed identity Container Apps scale rules can use managed identity to authenticate with Azure services. The following Bicep template passes in system-based managed identity to authenticate for an Azure Queue scaler. Before using the following code, replace the placeholders surrounded by `<>` with your values. ```bicep scale: { minReplicas: 0 maxReplicas: 4 rules: [ { name: 'azure-queue' custom: { type: 'azure-queue' metadata: { accountName: '' queueName: '' queueLength: '1' }, identity: 'system' } } ] } ``` To learn more about using managed identity with scale rules, see [Managed identity](managed-identity.md#scale-rules). ::: zone-end ::: zone pivot="azure-resource-manager" The following procedure shows you how to convert a KEDA scaler to a Container App scale rule. This snippet is an excerpt of an ARM template to show you where each section fits in context of the overall template. ```json { ... "resources": { ... "properties": { ... "configuration": { ... "secrets": [ { "name": "", "value": "" } ] }, "template": { ... "scale": { "minReplicas": 0, "maxReplicas": 5, "rules": [ { "name": "", "custom": { "metadata": { ... }, "auth": [ { "secretRef": "", "triggerParameter": "" } ] } } ] } } } } } ``` Refer to this excerpt for context on how the following examples fit in the ARM template. First, define the type and metadata of the scale rule. 1. From the KEDA scaler specification, find the `type` value. ```yml triggers: - type: azure-servicebus ⬅️ metadata: queueName: my-queue namespace: service-bus-namespace messageCount: "5" ``` 1. In the ARM template, enter the scaler `type` value into the `custom.type` property of the scale rule. ```yml ... "rules": [ { "name": "azure-servicebus-queue-rule", "custom": { "type": "azure-servicebus", ⬅️ "metadata": { "queueName": "my-queue", "namespace": "service-bus-namespace", "messageCount": "5" } } } ] ... ``` 1. From the KEDA scaler specification, find the `metadata` values. ```yml triggers: - type: azure-servicebus metadata: queueName: my-queue ⬅️ namespace: service-bus-namespace ⬅️ messageCount: "5" ⬅️ ``` 1. In the ARM template, add all metadata values to the `custom.metadata` section of the scale rule. ```json ... "rules": [ { "name": "azure-servicebus-queue-rule", "custom": { "type": "azure-servicebus", "metadata": { "queueName": "my-queue", ⬅️ "namespace": "service-bus-namespace", ⬅️ "messageCount": "5" ⬅️ } } } ] ... ``` ### Authentication Container Apps scale rules support secrets-based authentication. Scale rules for Azure resources, including Azure Queue Storage, Azure Service Bus, and Azure Event Hubs, also support managed identity. Where possible, use managed identity authentication to avoid storing secrets within the app. #### Use secrets To use secrets for authentication, create a secret in the container app's `secrets` array. Use the secret value in the `auth` array of the scale rule. KEDA scalers can use secrets in a [TriggerAuthentication](https://keda.sh/docs/latest/concepts/authentication/) that the `authenticationRef` property references. You can map the TriggerAuthentication object to the Container Apps scale rule. 1. Find the `TriggerAuthentication` object referenced by the KEDA `ScaledObject` specification. 1. In the `TriggerAuthentication` object, find each `secretTargetRef` and its associated secret. ```yml apiVersion: v1 kind: Secret metadata: name: my-secrets namespace: my-project type: Opaque data: connection-string-secret: ⬅️ --- apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: azure-servicebus-auth spec: secretTargetRef: - parameter: connection ⬅️ name: my-secrets ⬅️ key: connection-string-secret ⬅️ --- apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: azure-servicebus-queue-rule namespace: default spec: scaleTargetRef: name: my-scale-target triggers: - type: azure-servicebus metadata: queueName: my-queue namespace: service-bus-namespace messageCount: "5" authenticationRef: name: azure-servicebus-auth ``` 1. In the ARM template, for each secret: 1. Add a [secret](./manage-secrets.md) to the container app's `secrets` array containing the secret name and value. 1. Add an entry to the `auth` array of the scale rule. 1. Set the value of the `triggerParameter` property to the value of the `secretTargetRef`'s `parameter` property. 1. Set the value of the `secretRef` property to the name of the `secretTargetRef`'s `key` property. ```json { ... "resources": { ... "properties": { ... "configuration": { ... "secrets": [ { ⬅️ "name": "connection-string-secret", ⬅️ "value": "" ⬅️ } ⬅️ ] }, "template": { ... "scale": { "minReplicas": 0, "maxReplicas": 5, "rules": [ { "name": "azure-servicebus-queue-rule", "custom": { "type": "azure-servicebus", "metadata": { "queueName": "my-queue", "namespace": "service-bus-namespace", "messageCount": "5" }, "auth": [ { ⬅️ "secretRef": "connection-string-secret", ⬅️ "triggerParameter": "connection" ⬅️ } ⬅️ ] } } ] } } } } } ``` Some scalers support metadata with the `FromEnv` suffix to reference a value in an environment variable. Container Apps looks at the first container listed in the ARM template for the environment variable. Refer to the [considerations section](#considerations) for more security related information. #### Using managed identity Container Apps scale rules can use managed identity to authenticate with Azure services. The following ARM template passes in system-assigned managed identity to authenticate for an Azure Queue scaler. Before using the following code, replace the placeholders surrounded by `<>` with your values. ```json "scale": { "minReplicas": 0, "maxReplicas": 4, "rules": [ { "name": "azure-queue", "custom": { "type": "azure-queue", "metadata": { "accountName": "", "queueName": "", "queueLength": "1" }, "identity": "system" } } ] } ``` To learn more about using managed identity with scale rules, see [Managed identity](managed-identity.md#scale-rules). ::: zone-end ::: zone pivot="azure-cli" 1. From the KEDA scaler specification, find the `type` value. ```yml triggers: - type: azure-servicebus ⬅️ metadata: queueName: my-queue namespace: service-bus-namespace messageCount: "5" ``` 1. In the CLI command, set the `--scale-rule-type` parameter to the specification `type` value. ```azurecli az containerapp create \ --name \ --resource-group \ --environment \ --image --min-replicas 0 \ --max-replicas 5 \ --secrets "connection-string-secret=" \ --scale-rule-name azure-servicebus-queue-rule \ --scale-rule-type azure-servicebus \ ⬅️ --scale-rule-metadata "queueName=my-queue" \ "namespace=service-bus-namespace" \ "messageCount=5" \ --scale-rule-auth "connection=connection-string-secret" ``` 1. From the KEDA scaler specification, find the `metadata` values. ```yml triggers: - type: azure-servicebus metadata: queueName: my-queue ⬅️ namespace: service-bus-namespace ⬅️ messageCount: "5" ⬅️ ``` 1. In the CLI command, set the `--scale-rule-metadata` parameter to the metadata values. Transform the values from a YAML format to a key/value pair for use on the command line. Separate each key/value pair with a space. ```azurecli az containerapp create \ --name \ --resource-group \ --environment \ --image --min-replicas 0 \ --max-replicas 5 \ --secrets "connection-string-secret=" \ --scale-rule-name azure-servicebus-queue-rule \ --scale-rule-type azure-servicebus \ --scale-rule-metadata "queueName=my-queue" \ ⬅️ "namespace=service-bus-namespace" \ ⬅️ "messageCount=5" \ ⬅️ --scale-rule-auth "connection=connection-string-secret" ``` ### Authentication Container Apps scale rules support secrets-based authentication. Scale rules for Azure resources, including Azure Queue Storage, Azure Service Bus, and Azure Event Hubs, also support managed identity. Where possible, use managed identity authentication to avoid storing secrets within the app. #### Use secrets To configure secrets-based authentication for a Container Apps scale rule, configure the secrets in the container app and reference them in the scale rule. A KEDA scaler supports secrets in a [TriggerAuthentication](https://keda.sh/docs/latest/concepts/authentication/) which the `authenticationRef` property uses for reference. You can map the `TriggerAuthentication` object to the Container Apps scale rule. 1. Find the `TriggerAuthentication` object referenced by the KEDA `ScaledObject` specification. Identify each `secretTargetRef` of the `TriggerAuthentication` object. ```yml apiVersion: v1 kind: Secret metadata: name: my-secrets namespace: my-project type: Opaque data: connection-string-secret: ⬅️ --- apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: azure-servicebus-auth spec: secretTargetRef: - parameter: connection ⬅️ name: my-secrets ⬅️ key: connection-string-secret ⬅️ --- apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: azure-servicebus-queue-rule namespace: default spec: scaleTargetRef: name: my-scale-target triggers: - type: azure-servicebus metadata: queueName: my-queue namespace: service-bus-namespace messageCount: "5" authenticationRef: name: azure-servicebus-auth ``` 1. In your container app, create the [secrets](./manage-secrets.md) that match the `secretTargetRef` properties. 1. In the CLI command, set parameters for each `secretTargetRef` entry. 1. Create a secret entry with the `--secrets` parameter. If there are multiple secrets, separate them with a space. 1. Create an authentication entry with the `--scale-rule-auth` parameter. If there are multiple entries, separate them with a space. ```azurecli az containerapp create \ --name \ --resource-group \ --environment \ --image --min-replicas 0 \ --max-replicas 5 \ --secrets "connection-string-secret=" \ ⬅️ --scale-rule-name azure-servicebus-queue-rule \ --scale-rule-type azure-servicebus \ --scale-rule-metadata "queueName=my-queue" \ "namespace=service-bus-namespace" \ "messageCount=5" \ --scale-rule-auth "connection=connection-string-secret" ⬅️ ``` #### Using managed identity Container Apps scale rules can use managed identity to authenticate with Azure services. The following command creates a container app with a user-assigned managed identity and uses it to authenticate for an Azure Queue scaler. Before using the following code, replace the placeholders surrounded by `<>` with your values. ```bash az containerapp create \ --resource-group \ --name \ --environment \ --user-assigned \ --scale-rule-name azure-queue \ --scale-rule-type azure-queue \ --scale-rule-metadata "accountName=" "queueName=queue1" "queueLength=1" \ --scale-rule-identity ``` ::: zone-end ::: zone pivot="azure-portal" 1. Go to your container app in the Azure portal. 1. Select **Scale**. 1. Select **Edit and deploy**. 1. Select the **Scale and replicas** tab. 1. Select the minimum and maximum replica range. :::image type="content" source="media/scale-app/azure-container-apps-scale-slide.png" alt-text="Screenshot of Azure Container Apps scale range slider."::: 1. Select **Add**. 1. In the *Rule name* box, enter a rule name. 1. From the *Type* dropdown, select **Custom**. 1. From the KEDA scaler specification, find the `type` value. ```yml triggers: - type: azure-servicebus ⬅️ metadata: queueName: my-queue namespace: service-bus-namespace messageCount: "5" ``` 1. In the *Custom rule type* box, enter the scaler `type` value. 1. From the KEDA scaler specification, find the `metadata` values. ```yml triggers: - type: azure-servicebus metadata: queueName: my-queue ⬅️ namespace: service-bus-namespace ⬅️ messageCount: "5" ⬅️ ``` 1. In the portal, find the *Metadata* section and select **Add**. Enter the name and value for each item in the KEDA `ScaledObject` specification metadata section. ### Authentication Container Apps scale rules support secrets-based authentication. Scale rules for Azure resources, including Azure Queue Storage, Azure Service Bus, and Azure Event Hubs, also support managed identity. Where possible, use managed identity authentication to avoid storing secrets within the app. #### Use secrets 1. In your container app, create the [secrets](./manage-secrets.md) that you want to reference. 1. Find the `TriggerAuthentication` object referenced by the KEDA `ScaledObject` specification. Identify each `secretTargetRef` of the `TriggerAuthentication` object. ```json apiVersion: v1 kind: Secret metadata: name: my-secrets namespace: my-project type: Opaque data: connection-string-secret: --- apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: azure-servicebus-auth spec: secretTargetRef: - parameter: connection ⬅️ name: my-secrets ⬅️ key: connection-string-secret ⬅️ --- apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: azure-servicebus-queue-rule namespace: default spec: scaleTargetRef: name: my-scale-target triggers: - type: azure-servicebus metadata: queueName: my-queue namespace: service-bus-namespace messageCount: "5" authenticationRef: name: azure-servicebus-auth ``` 1. In the *Authentication* section, select **Add** to create an entry for each KEDA `secretTargetRef` parameter. #### Using managed identity Managed identity authentication isn't supported in the Azure portal. Use the [Azure CLI](scale-app.md?pivots=azure-cli#authentication) or [Azure Resource Manager](scale-app.md?&pivots=azure-resource-manager#authentication) to authenticate using managed identity. ::: zone-end ## Default scale rule If you don't create a scale rule, the default scale rule is applied to your container app. | Trigger | Min replicas | Max replicas | |--|--|--| | HTTP | 0 | 10 | > [!IMPORTANT] > Make sure you create a scale rule or set `minReplicas` to 1 or more if you don't enable ingress. If ingress is disabled and you don't define a `minReplicas` or a custom scale rule, your container app scales to zero and has no way of starting back up. ## Scale behavior Scaling has the following behaviors: | Behavior | Value | |--|--| | Polling interval | 30 seconds | | Cool down period | 300 seconds | | Scale up stabilization window | 0 seconds | | Scale down stabilization window | 300 seconds | | Scale up step | 1, 4, 8, 16, 32, ... up to configured maximum replica count | | Scale down step | 100% of replicas that need to shut down | | Scaling algorithm | `desiredReplicas = ceil(currentMetricValue / targetMetricValue)` | - **Polling interval** is how frequently KEDA queries event sources. This value doesn't apply to HTTP and TCP scale rules. - **Cool down period** is how long after the last event KEDA waits before the application scales down to its minimum replica count. - **Scale up stabilization window** is how long KEDA waits before it performs a scale up decision once scale up conditions are met. - **Scale down stabilization window** is how long KEDA waits before it performs a scale down decision once scale down conditions are met. - **Scale up step** is how many replicas are added as your container app scales out. It starts at 1, then increases to 4, 8, 16, 32, and so on, up to the configured maximum replica count. - **Scale down step** is how many replicas are removed as your container app scales in. KEDA removes 100% of replicas that need to shut down. - **Scaling algorithm** is the formula used to calculate the current desired number of replicas. ### Example For the following scale rule: ```json "minReplicas": 0, "maxReplicas": 20, "rules": [ { "name": "azure-servicebus-queue-rule", "custom": { "type": "azure-servicebus", "metadata": { "queueName": "my-queue", "namespace": "service-bus-namespace", "messageCount": "5" } } } ] ``` As your app scales out, KEDA starts with an empty queue and performs the following steps: 1. Check `my-queue` every 30 seconds. 1. If the queue length equals 0, go back to step 1. 1. If the queue length is greater than 0, scale the app to 1. 1. If the queue length is 50, calculate `desiredReplicas = ceil(50/5) = 10`. 1. Scale app to `min(maxReplicaCount, desiredReplicas, max(4, 2*currentReplicaCount))`. 1. Go back to step 1. If the app scales to the maximum replica count of 20, scaling goes through the same previous steps. Scale down only happens if the condition is satisfied for 300 seconds (scale down stabilization window). Once the queue length is 0, KEDA waits for 300 seconds (cool down period) before scaling the app to 0. ## Considerations - In "multiple revisions" mode, adding a new scale trigger creates a new revision of your application but your old revision remains available with the old scale rules. Use the **Revision management** page to manage traffic allocations. - You don't incur any usage charges when an application scales to zero. For more pricing information, see [Billing in Azure Container Apps](billing.md). - You need to enable data protection for all .NET apps on Azure Container Apps. See [Deploying and scaling an ASP.NET Core app on Azure Container Apps](/aspnet/core/host-and-deploy/scaling-aspnet-apps/scaling-aspnet-apps) for details. ### Known limitations - Vertical scaling isn't supported. - Replica quantities are a target amount, not a guarantee. - If you're using [Dapr actors](https://docs.dapr.io/developing-applications/building-blocks/actors/actors-overview/) to manage states, keep in mind that scaling to zero isn't supported. Dapr uses virtual actors to manage asynchronous calls, which means their in-memory representation isn't tied to their identity or lifetime. - Changing KEDA proxies through the [proxies](https://keda.sh/docs/2.16/operate/cluster/#http-proxies) settings isn't supported. Consider using Workload Profiles with a NAT Gateway or User Defined Route (UDR) to send traffic to a network appliance, where you can inspect or proxy traffic. ## Next steps > [!div class="nextstepaction"] > [Manage secrets](manage-secrets.md)