Skip to main content
Azure·
Sep 2026
·
6 min read

Azure Container Apps: Designing for Scale-to-Zero in Production

A deep dive into cold-start mitigation, KEDA HTTP scaler tuning, and ingress routing when building cost-optimized microservices on ACA.

#Azure#Container Apps#KEDA#Microservices#Cost Optimization
01

The Allure and Reality of Scale-to-Zero

Scale-to-zero is often advertised as the holy grail of cloud economics: pay absolutely nothing when your service is idle. In Azure Container Apps (ACA), powered by KEDA (Kubernetes Event-driven Autoscaling), scaling to zero replicas is remarkably straightforward to configure. However, deploying scale-to-zero in production environments reveals immediate trade-offs that can degrade user experience if not accounted for.

Scale-to-zero is ideal for asynchronous event processors, webhooks, and internal tools, but requires careful cold-start planning for user-facing HTTP APIs.

02

The Cold Start Problem in Container Runtimes

When the replica count drops to 0, incoming HTTP requests must trigger the KEDA HTTP add-on to allocate container resources, pull the container image (if not cached on the host), start the entrypoint process, and pass the readiness probe before the request can be serviced. In standard ACA environments, this cold-start delay typically ranges between 3 to 12 seconds depending on image size and runtime bootstrap time.
container-app-scale.yamlyaml
scale:
  minReplicas: 0
  maxReplicas: 10
  rules:
  - name: http-scaling-rule
    http:
      metadata:
        concurrentRequests: "50"
03

Mitigation Strategies & Production Architecture

To achieve cost savings without sacrificing customer responsiveness, we implemented a hybrid tiered scaling model. Critical user-facing microservices maintain minReplicas=1 during business hours using scheduled KEDA cron triggers, and scale to zero only during designated maintenance and overnight windows. For batch workers and asynchronous event handlers, scale-to-zero remains active 24/7.
cron-scale-rule.yamlyaml
rules:
- name: business-hours-cron
  custom:
    type: cron
    metadata:
      timezone: "UTC"
      start: "0 8 * * 1-5"
      end: "0 20 * * 1-5"
      desiredReplicas: "1"
04

Key Lessons Learned

1. Optimize your container image footprint: Multi-stage Docker builds using Alpine or Distroless images cut cold-start pull times by over 60%. 2. Tune readiness probes: Ensure your health probe returns HTTP 200 immediately once the HTTP listener is bound, rather than waiting for heavy background tasks to complete. 3. Measure before you optimize: Continuously monitor request duration percentiles (p95, p99) in Log Analytics to detect cold-start spikes.