🎤Speaking at KubeCon EU 2026Lessons Learned Orchestrating Multi-Tenant GPUs on OpenShift AIView Session
Autoscaling intermediate ⏱ 15 minutes K8s 1.28+

How to Implement Pod Autoscaling with KEDA

Scale workloads based on external events with KEDA. Configure scalers for queues, databases, Prometheus metrics, and custom sources.

By Luca Berton

How to Implement Pod Autoscaling with KEDA

KEDA (Kubernetes Event-driven Autoscaling) scales workloads based on external metrics and events. Scale to zero and handle event-driven workloads efficiently.

Install KEDA

# Install with Helm
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --namespace keda --create-namespace

# Or with kubectl
kubectl apply --server-side -f https://github.com/kedacore/keda/releases/download/v2.13.0/keda-2.13.0.yaml

# Verify installation
kubectl get pods -n keda

KEDA Components

# ScaledObject - For Deployments/StatefulSets
# ScaledJob - For Jobs
# TriggerAuthentication - For secrets/credentials

# KEDA manages HPA automatically
# Can scale to/from zero (unlike standard HPA)

Scale on RabbitMQ Queue

# rabbitmq-scaler.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: rabbitmq-scaler
  namespace: production
spec:
  scaleTargetRef:
    name: queue-worker  # Deployment name
  minReplicaCount: 0    # Scale to zero!
  maxReplicaCount: 50
  pollingInterval: 15   # Check every 15 seconds
  cooldownPeriod: 300   # Wait 5 min before scale down
  triggers:
    - type: rabbitmq
      metadata:
        host: amqp://user:pass@rabbitmq.default.svc:5672
        queueName: orders
        mode: QueueLength
        value: "5"  # Scale up at 5 messages per replica

Scale on AWS SQS

# sqs-scaler.yaml
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: aws-credentials
spec:
  secretTargetRef:
    - parameter: awsAccessKeyID
      name: aws-secrets
      key: AWS_ACCESS_KEY_ID
    - parameter: awsSecretAccessKey
      name: aws-secrets
      key: AWS_SECRET_ACCESS_KEY
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: sqs-scaler
spec:
  scaleTargetRef:
    name: sqs-worker
  minReplicaCount: 0
  maxReplicaCount: 100
  triggers:
    - type: aws-sqs-queue
      authenticationRef:
        name: aws-credentials
      metadata:
        queueURL: https://sqs.us-east-1.amazonaws.com/123456789/my-queue
        queueLength: "10"
        awsRegion: us-east-1

Scale on Kafka

# kafka-scaler.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer
spec:
  scaleTargetRef:
    name: kafka-consumer
  minReplicaCount: 1
  maxReplicaCount: 50
  triggers:
    - type: kafka
      metadata:
        bootstrapServers: kafka.default.svc:9092
        consumerGroup: my-consumer-group
        topic: events
        lagThreshold: "100"  # Scale when lag > 100
        activationLagThreshold: "10"  # Start from 0 at lag 10

Scale on Prometheus Metrics

# prometheus-scaler.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: prometheus-scaler
spec:
  scaleTargetRef:
    name: api-server
  minReplicaCount: 2
  maxReplicaCount: 20
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus.monitoring.svc:9090
        metricName: http_requests_per_second
        query: sum(rate(http_requests_total{app="api"}[2m]))
        threshold: "100"  # Scale at 100 RPS

Scale on Redis List

# redis-scaler.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: redis-worker
spec:
  scaleTargetRef:
    name: redis-processor
  minReplicaCount: 0
  maxReplicaCount: 30
  triggers:
    - type: redis
      metadata:
        address: redis.default.svc:6379
        listName: job-queue
        listLength: "10"
        databaseIndex: "0"

Scale on PostgreSQL Query

# postgres-scaler.yaml
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: postgres-auth
spec:
  secretTargetRef:
    - parameter: connection
      name: postgres-secrets
      key: connection-string
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: postgres-scaler
spec:
  scaleTargetRef:
    name: db-processor
  minReplicaCount: 0
  maxReplicaCount: 20
  triggers:
    - type: postgresql
      authenticationRef:
        name: postgres-auth
      metadata:
        query: "SELECT COUNT(*) FROM jobs WHERE status='pending'"
        targetQueryValue: "5"

Scale on HTTP Traffic

# http-scaler.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: http-scaler
spec:
  scaleTargetRef:
    name: web-app
  minReplicaCount: 1
  maxReplicaCount: 50
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus.monitoring.svc:9090
        query: |
          sum(rate(nginx_ingress_controller_requests{
            namespace="production",
            service="web-app"
          }[2m]))
        threshold: "100"

Multiple Triggers

# multi-trigger.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: multi-scaler
spec:
  scaleTargetRef:
    name: worker
  minReplicaCount: 1
  maxReplicaCount: 100
  triggers:
    # Scale on either condition
    - type: rabbitmq
      metadata:
        host: amqp://rabbitmq.svc:5672
        queueName: high-priority
        queueLength: "1"
    - type: rabbitmq
      metadata:
        host: amqp://rabbitmq.svc:5672
        queueName: normal
        queueLength: "10"

ScaledJob (For Jobs)

# scaled-job.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
  name: batch-processor
spec:
  jobTargetRef:
    parallelism: 1
    completions: 1
    template:
      spec:
        containers:
          - name: processor
            image: batch-processor:v1
            env:
              - name: QUEUE_URL
                value: "amqp://rabbitmq.svc:5672"
        restartPolicy: Never
  pollingInterval: 30
  successfulJobsHistoryLimit: 5
  failedJobsHistoryLimit: 5
  maxReplicaCount: 50
  triggers:
    - type: rabbitmq
      metadata:
        host: amqp://rabbitmq.svc:5672
        queueName: batch-jobs
        mode: QueueLength
        value: "1"  # One job per message

Scaling Behavior

# advanced-scaling.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: advanced-scaler
spec:
  scaleTargetRef:
    name: my-app
  minReplicaCount: 2
  maxReplicaCount: 100
  pollingInterval: 15
  cooldownPeriod: 300
  advanced:
    horizontalPodAutoscalerConfig:
      behavior:
        scaleDown:
          stabilizationWindowSeconds: 300
          policies:
            - type: Percent
              value: 10
              periodSeconds: 60
        scaleUp:
          stabilizationWindowSeconds: 0
          policies:
            - type: Percent
              value: 100
              periodSeconds: 15
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus.svc:9090
        query: sum(rate(requests_total[1m]))
        threshold: "50"

Monitor KEDA

# Check ScaledObjects
kubectl get scaledobject -A
kubectl describe scaledobject my-scaler

# Check created HPA
kubectl get hpa

# KEDA operator logs
kubectl logs -n keda -l app=keda-operator

# Metrics server logs
kubectl logs -n keda -l app=keda-metrics-apiserver

# Debug scaling
kubectl get scaledobject my-scaler -o yaml | grep -A20 status

Summary

KEDA extends Kubernetes autoscaling with 50+ event sources. Create ScaledObjects for Deployments that can scale to zero. Use TriggerAuthentication for secure credential management. Configure triggers for queues (RabbitMQ, SQS, Kafka), databases (PostgreSQL, Redis), metrics (Prometheus), and more. ScaledJobs spawn Jobs based on events. Use multiple triggers to scale on any condition. Monitor with kubectl get scaledobject and check operator logs for debugging.


📘 Go Further with Kubernetes Recipes

Love this recipe? There’s so much more! This is just one of 100+ hands-on recipes in our comprehensive Kubernetes Recipes book.

Inside the book, you’ll master:

  • ✅ Production-ready deployment strategies
  • ✅ Advanced networking and security patterns
  • ✅ Observability, monitoring, and troubleshooting
  • ✅ Real-world best practices from industry experts

“The practical, recipe-based approach made complex Kubernetes concepts finally click for me.”

👉 Get Your Copy Now — Start building production-grade Kubernetes skills today!

#keda #autoscaling #events #scaling #serverless

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.