Subchapter 12.22
keda-scaler.mdMarkdown6 KBView on GitHub
Scale agent pods to zero when idle, up when work arrives — driven by GitHub Issues.
When running Squad on Kubernetes, agent pods sit idle when no work exists. KEDA (opens in a new tab) (Kubernetes Event-Driven Autoscaler) solves this for queue-based workloads, but GitHub Issues isn’t a native KEDA trigger.
The keda-copilot-scaler is a KEDA External Scaler (gRPC) that bridges this gap:
squad:copilot)repo scopehelm install keda-copilot-scaler oci://ghcr.io/tamirdresher/keda-copilot-scaler \
--namespace squad-scaler --create-namespace \
--set github.owner=YOUR_ORG \
--set github.repo=YOUR_REPO \
--set github.token=YOUR_TOKENOr with Kustomize:
kubectl apply -k https://github.com/tamirdresher/keda-copilot-scaler/deploy/kustomizeapiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: picard-scaler
namespace: squad
spec:
scaleTargetRef:
name: picard-deployment
minReplicaCount: 0 # Scale to zero when idle
maxReplicaCount: 3
pollingInterval: 30 # Check every 30 seconds
cooldownPeriod: 300 # Wait 5 minutes before scaling down
triggers:
- type: external
metadata:
scalerAddress: keda-copilot-scaler.squad-scaler.svc.cluster.local:6000
owner: your-org
repo: your-repo
labels: squad:copilot # Only count issues with this label
threshold: "1" # Scale up when >= 1 issue exists# Check the scaler is running
kubectl get pods -n squad-scaler
# Check ScaledObject status
kubectl get scaledobject picard-scaler -n squad
# Watch scaling events
kubectl get events -n squad --watch| Open Issues | Target Replicas | Behavior |
|---|---|---|
| 0 | 0 | Scale to zero — save resources |
| 1–3 | 1 | Single agent handles work |
| 4–10 | 2 | Scale up for parallel processing |
| 10+ | 3 (max) | Maximum parallelism |
The threshold and max replicas are configurable per ScaledObject.
The scaler tracks GitHub API rate limits:
X-RateLimit-Remaining from API responsesCombine with machine capability labels for intelligent scheduling:
# Only scale pods on GPU-capable nodes
spec:
template:
spec:
nodeSelector:
node.squad.dev/gpu: "true"
triggers:
- type: external
metadata:
labels: squad:copilot,needs:gpuThe scaler exposes rate limit metrics that feed into the cooperative rate limiting system:
X-RateLimit-Remaining valueGitHub API KEDA Kubernetes
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ Issues │◄── poll ──►│ Scaler │──metrics─►│ HPA / KEDA │
│ (REST) │ │ (gRPC) │ │ Controller │
└──────────┘ └──────────┘ └──────┬───────┘
│
scale up/down
│
┌──────▼───────┐
│ Agent Pods │
│ (0–N replicas)│
└──────────────┘| Parameter | Default | Description |
|---|---|---|
github.owner | — | Repository owner |
github.repo | — | Repository name |
github.token | — | GitHub PAT with repo scope |
github.labels | squad:copilot | Comma-separated label filter |
scaler.port | 6000 | gRPC server port |
scaler.pollInterval | 30s | GitHub API polling interval |
scaler.rateLimitThreshold | 100 | Stop polling below this remaining |
The scaler is maintained as a standalone project. PRs and issues welcome.