Blog Post

Apps on Azure Blog
3 MIN READ

Configure time-based scaling in Azure Container Apps

wanjing's avatar
wanjing
Icon for Microsoft rankMicrosoft
Apr 01, 2025

Azure Container Apps leverages cron-type KEDA scaling rules to schedule autoscaling actions at specific times. This feature is ideal for applications with predictable workload fluctuations (e.g., batch jobs, reporting systems) that require scaling based on time-of-day or day-of-week patterns. This guide walks you through configuring and optimizing time-based scaling.

Prerequisites

  • An active Azure subscription with access to Azure Container Apps.
  • Basic understanding of KEDA (Kubernetes Event-driven Autoscaling) concepts.
  • A deployed application in Azure Container Apps (see Quickstart Guide).

How Time-Based Scaling Works

Time-based scaling in Azure Container Apps is achieved by defining cron-type scale rules(https://keda.sh/docs/2.15/scalers/cron/). It uses cron expressions to define start and end times for scaling actions. During the active window, the app scales to a specified desiredReplicas count. Outside this window, scaling defaults to minReplicas/maxReplicas settings.

Configuration Example: Weekday vs. Weekend Scaling

Scale to 1 replica on weekdays (Mon–Fri) and 0 replicas on weekends (Sat–Sun) to optimize costs.

triggers:
- type: cron
  metadata:
    timezone: Asia/Shanghai   # Uses TZ database names (e.g., "America/New_York")
    start: "0 8 * * 1"        # 08:00 AM every Monday (1 = Monday in cron syntax)
    end: "0 0 * * 6"          # 00:00 (midnight) every Saturday (6 = Saturday)
    desiredReplicas: "1"      # Maintain 1 replica during active period

Key Parameters Explained

ParameterDescription
typeSet to cron for time-based scaling.
timezoneTimezone for cron schedules (e.g., Europe/London). Full list.
start / endCron expressions defining the active window.
desiredReplicasReplica count during the start–end window.

Cron Syntax Notes:

  • Format: [minute] [hour] [day] [month] [day-of-week] (e.g., 0 8 * * 1 = 8:00 AM every Monday).
  • Days: 0 = Sunday, 1 = Monday, ..., 6 = Saturday.

Step-by-Step Configuration

Azure Portal:

  1. Navigate to your Container App in the Azure portal.
  2. Under Application, select Scale.
  3. Add a new scaling rule:
    • Rule Type: Select Custom → cron.
    • Metadata: Add timezone, start, end, and desiredReplicas (use the example above).
  4. Save changes.

Azure CLI:

By running below CLI command, we can create a add a new time-based scale rule.

az containerapp update \
  --name <APP_NAME> \
  --resource-group <RESOURCE_GROUP> \
  --environment <ENVIRONMENT_NAME> \
  --min-replicas 0 \
  --max-replicas 1 \
  --scale-rule-name "weekdayscale" \
  --scale-rule-type "cron" \
  --scale-rule-metadata "timezone=Asia/Shanghai" "start=0 8 * * 1" "end=0 0 * * 6" "desiredReplicas=1"

ARM Template:

This snippet is an excerpt of an ARM template to show you where each section fits in context of the overall template.

{
  "scale": {
    "minReplicas": 0,
    "maxReplicas": 1,
    "rules": [
      {
        "name": "weekdayscale",
        "type": "cron",
        "metadata": {
          "timezone": "Asia/Shanghai",
          "start": "0 8 * * 1",
          "end": "0 0 * * 6",
          "desiredReplicas": "1"
        }
      }
    ]
  }
}

Benefits of time-based scaling

  1. Cost efficiency: Scale down during off-peak hours to minimize resource costs.
  2. Resource optimization: Automatically adjust resources to align with predictable workload patterns.
  3. Simplicity: Straightforward configuration and management of scaling rules based on time intervals.

Conclusion

Time-based scaling in Azure Container Apps simplifies resource management for time-sensitive workloads. By combining cron schedules with KEDA, you can automate scaling actions to match demand while minimizing costs. For advanced scenarios, explore KEDA cron scaler documentation and Azure Container Apps scaling guide.

Updated Apr 01, 2025
Version 1.0
  • Thanks for the blog post. I have been trying to solve exactly this but somehow it does not work.  Here are my KEDA rules:

    param scalingrules array = [
      {
        name: 'cpu-scale-rule'
        custom: {
          type: 'cpu'
          metadata: {
            type: 'Utilization'
            value: '70'
          }
        }
      }
      {
        name: 'memory-scale-rule'
        custom: {
          type: 'memory'
          metadata: {
            type: 'Utilization'
            value: '70'
          }
        }
      }
    ]
    
    // Extra cron-regler för test och stage (ej prod)
    var cronScalingRules = environment != 'prod' ? [
      {
        name: 'scale-up-office-hours'
        custom: {
          type: 'cron'
          metadata: {
            timezone: 'Europe/Stockholm'
            start: '0 7 * * 1-5'   // mån–fre 07:00
            end: '0 20 * * 1-5'    // mån–fre 20:00
            desiredReplicas: '1'
          }
        }
      }
      {
        name: 'scale-down-weeknights'
        custom: {
          type: 'cron'
          metadata: {
            timezone: 'Europe/Stockholm'
            start: '0 20 * * 1-4'  // mån–tors 20:00
            end: '0 7 * * 2-5'     // tis–fre 07:00
            desiredReplicas: '0'
          }
        }
      }
      {
        name: 'scale-down-weekend'
        custom: {
          type: 'cron'
          metadata: {
            timezone: 'Europe/Stockholm'
            start: '0 20 * * 5'    // fredag 20:00
            end: '0 7 * * 1'       // måndag 07:00
            desiredReplicas: '0'
          }
        }
      }
    ] : [] // Tom array för prod-miljö
    
    // Slå samman reglerna
    var combinedScalingRules = concat(scalingrules, cronScalingRules)
    
    ....
          scale: {
            minReplicas: environment != 'prod' ? 0 : minReplicas
            maxReplicas: maxReplicas
            rules: combinedScalingRules
          }

     

    I can see the KEDA rules in the Azure portal, but the do not get triggered

    • wanjing's avatar
      wanjing
      Icon for Microsoft rankMicrosoft

      hi Mattias_Lindgren  Thank you for your message. According to the KEDA documentation: Cron | KEDA, it's recommended to set minReplicaCount to 0 instead of using desiredReplicas set to 0. Please try adjusting your logic to scale to 1 replica during business hours; otherwise, it will automatically scale down to 0. If you still encounter issues, could you please submit a support ticket to us so we can review the logs?