Migrate from HTTPScaledObject to InterceptorRoute Latest
How to migrate existing HTTPScaledObject resources to the InterceptorRoute API
This guide shows you how to migrate existing HTTPScaledObject (v1alpha1) resources to the InterceptorRoute (v1beta1) API.
Prerequisites
- KEDA HTTP Add-on v0.14.0 or later deployed on the cluster
kubectlaccess to the cluster- Existing
HTTPScaledObjectresources to migrate
What changed
The InterceptorRoute API replaces HTTPScaledObject with a cleaner separation of concerns.
- Manual ScaledObject management:
The
InterceptorRoutecontroller no longer creates a KEDAScaledObjectfor you. You create and manage it yourself, with access to all supported KEDA ScaledObject fields. - Multiple routing rules:
A new
rules[]structure lets you define multiple routing rules on a single resource, each with its own hosts, paths, and headers. - Target reference for routing only:
The target reference contains only
serviceandport/portName. Workload fields (name,apiVersion,kind) move to theScaledObjectwhere they belong. - Flexible scaling metrics: Concurrency and request rate can be used independently or together. When both are set, KEDA scales based on whichever metric demands more replicas.
- Granular timeouts:
A new
requesttimeout controls the full request lifecycle.conditionWaitis renamed toreadinessfor clarity. targetValueis required: OnHTTPScaledObject,targetValuedefaulted to100when omitted. OnInterceptorRoute,targetValuemust be set explicitly. If yourHTTPScaledObjectrelied on the default, addtargetValue: 100(or your preferred value) when migrating.- Scaling fields move to ScaledObject:
replicas,targetPendingRequests,scaledownPeriod, andinitialCooldownPeriodare configured on the KEDAScaledObjectdirectly.
Convert an HTTPScaledObject to an InterceptorRoute
The migration is a direct field-by-field conversion. The Apply the migration without downtime section below shows how to perform the switchover without interrupting traffic.
Before: HTTPScaledObject
apiVersion: http.keda.sh/v1alpha1
kind: HTTPScaledObject
metadata:
name: my-app
namespace: default
spec:
hosts:
- app.example.com
pathPrefixes:
- /api
- /health
headers:
- name: X-Custom-Header
value: "my-value"
scaleTargetRef:
name: my-app
kind: Deployment
apiVersion: apps/v1
service: my-app-svc
port: 8080
coldStartTimeoutFailoverRef:
service: fallback-svc
port: 8080
timeoutSeconds: 45
replicas:
min: 0
max: 10
scalingMetric:
concurrency:
targetValue: 50
timeouts:
conditionWait: 30s
responseHeader: 10s
scaledownPeriod: 120
After: InterceptorRoute and ScaledObject
The single HTTPScaledObject becomes two resources: an InterceptorRoute for routing and an independently managed ScaledObject for scaling.
InterceptorRoute:
apiVersion: http.keda.sh/v1beta1
kind: InterceptorRoute
metadata:
name: my-app
namespace: default
spec:
target:
service: my-app-svc
port: 8080
coldStart:
fallback:
service: fallback-svc
port: 8080
rules:
- hosts:
- app.example.com
paths:
- value: /api
- value: /health
headers:
- name: X-Custom-Header
value: "my-value"
scalingMetric:
concurrency:
targetValue: 50
timeouts:
readiness: 45s
responseHeader: 10s
ScaledObject:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: my-app
namespace: default
spec:
scaleTargetRef:
name: my-app
kind: Deployment
apiVersion: apps/v1
minReplicaCount: 0
maxReplicaCount: 10
cooldownPeriod: 120
triggers:
- type: external-push
metadata:
scalerAddress: "keda-add-ons-http-external-scaler.keda:9090"
interceptorRoute: "my-app"
Note the following conversions:
scaleTargetRefbecomestargetwith onlyserviceandport/portName.hosts,pathPrefixes, andheadersmove into arules[]entry.pathPrefixesentries becomepathsentries, each with avaluefield.coldStartTimeoutFailoverRefsplits: the service reference moves tocoldStart.fallback, andtimeoutSecondsmoves totimeouts.readinessas a duration string ("45s").replicas,scaledownPeriod, andinitialCooldownPeriodmove to theScaledObject.- The workload reference (
name,apiVersion,kind) moves to theScaledObject’sscaleTargetRef.
Apply the migration without downtime
The HTTPScaledObject controller sets an owner reference on the KEDA ScaledObject it creates.
Deleting the HTTPScaledObject triggers Kubernetes garbage collection, which cascade-deletes the owned ScaledObject.
To prevent this, add the httpscaledobject.keda.sh/orphan-scaledobject annotation to the HTTPScaledObject before deleting it.
The controller removes the owner reference from the ScaledObject, so it survives deletion.
Set these environment variables before running the commands:
NAME=my-app
NAMESPACE=default
Annotate the
HTTPScaledObjectto orphan itsScaledObject:kubectl annotate httpscaledobject $NAME -n $NAMESPACE \ httpscaledobject.keda.sh/orphan-scaledobject=trueThe controller removes the owner reference from the
ScaledObject. Verify that the owner reference was removed:kubectl get scaledobject $NAME -n $NAMESPACE \ -o jsonpath='{.metadata.ownerReferences}'The output is empty when the owner reference has been removed.
Create the
InterceptorRoute:kubectl apply -f interceptor-route.yamlWhen the
InterceptorRouteshares the same namespace and name as theHTTPScaledObject, the routing table automatically gives theInterceptorRouteprecedence and skips theHTTPScaledObject.Update the
ScaledObjecttrigger metadata. The auto-createdScaledObjectreferences theHTTPScaledObjectby name in its trigger metadata. ReplacehttpScaledObjectwithinterceptorRouteso the external scaler resolves metrics from theInterceptorRoute:kubectl patch scaledobject $NAME -n $NAMESPACE --type=json \ -p '[{"op": "remove", "path": "/spec/triggers/0/metadata/httpScaledObject"}, {"op": "add", "path": "/spec/triggers/0/metadata/interceptorRoute", "value": "'$NAME'"}]'Also compare the remaining fields with the ScaledObject YAML from the conversion example and adjust
minReplicaCount,maxReplicaCount, orcooldownPeriodas needed.Verify the
ScaledObjectis still present and active:kubectl get scaledobject $NAME -n $NAMESPACEDelete the old
HTTPScaledObject:kubectl delete httpscaledobject $NAME -n $NAMESPACEThe
ScaledObjectremains in the cluster because the owner reference was removed in step 1.
GitOps: In one commit, add the orphan annotation to the
HTTPScaledObjectmanifest, add theInterceptorRoutemanifest, and update theScaledObjecttrigger metadata (httpScaledObject→interceptorRoute). In the next commit, remove theHTTPScaledObjectmanifest.
Field mapping
HTTPScaledObject → InterceptorRoute
| HTTPScaledObject field | InterceptorRoute field |
|---|---|
spec.hosts | spec.rules[].hosts |
spec.pathPrefixes | spec.rules[].paths[].value |
spec.headers | spec.rules[].headers |
spec.scaleTargetRef.service | spec.target.service |
spec.scaleTargetRef.port | spec.target.port |
spec.scaleTargetRef.portName | spec.target.portName |
spec.coldStartTimeoutFailoverRef.service | spec.coldStart.fallback.service |
spec.coldStartTimeoutFailoverRef.port | spec.coldStart.fallback.port |
spec.coldStartTimeoutFailoverRef.portName | spec.coldStart.fallback.portName |
spec.coldStartTimeoutFailoverRef.timeoutSeconds | spec.timeouts.readiness (as Duration, e.g. "30s") |
spec.scalingMetric.concurrency.targetValue | spec.scalingMetric.concurrency.targetValue |
spec.scalingMetric.requestRate.targetValue | spec.scalingMetric.requestRate.targetValue |
spec.scalingMetric.requestRate.window | spec.scalingMetric.requestRate.window |
spec.scalingMetric.requestRate.granularity | spec.scalingMetric.requestRate.granularity |
spec.targetPendingRequests | spec.scalingMetric |
spec.timeouts.conditionWait | spec.timeouts.readiness |
spec.timeouts.responseHeader | spec.timeouts.responseHeader |
| (new) | spec.timeouts.request |
HTTPScaledObject → ScaledObject
| HTTPScaledObject field | ScaledObject field |
|---|---|
spec.scaleTargetRef.name | spec.scaleTargetRef.name |
spec.scaleTargetRef.apiVersion | spec.scaleTargetRef.apiVersion |
spec.scaleTargetRef.kind | spec.scaleTargetRef.kind |
spec.replicas.min | spec.minReplicaCount |
spec.replicas.max | spec.maxReplicaCount |
spec.scaledownPeriod | spec.cooldownPeriod |
spec.initialCooldownPeriod | spec.initialCooldownPeriod |
What’s Next
- Configure Routing Rules — multiple rules, host, path, and header matching on an InterceptorRoute.
- Configure Scaling Metrics — concurrency, request rate, and combined metric configuration.
- InterceptorRoute Reference — full API specification.
- KEDA ScaledObject documentation — scaling configuration options.