---
id: w1/m4/t002
title: Spike — KEDA HTTP add-on vs custom activator (pick the wake mechanism)
worker: worker1
status: done
estimate: 30m
depends_on: [w1/m4/t001]
---

## Objective

Decide HOW to wake a 0-replica app on request.

## Decision: Custom activator over KEDA HTTP add-on

**Chose custom.** Reasons:

1. **No external operator dependency** — KEDA requires installing the KEDA operator and the HTTP add-on controller as cluster infrastructure. bex already owns the Ingress, the App CR, and the operator reconcile loop; adding KEDA duplicates effort.
2. **Render went custom and so should we** — Render built with Knative, hit per-app overhead, ripped it out, and built a custom activator. KEDA's add-on is lighter than Knative but still has per-app HTTPScaledObject CRs with a controller watching them cluster-wide. We start where they ended.
3. **We already own the control surface** — the operator controls the Ingress backend. Switching it from the app Service to a lightweight activator is 10 lines of Go; no KEDA wiring needed.
4. **Less to operate** — one additional bex binary (`/activator` from the same image), one Service, one RBAC binding. No new CRDs.

The custom path: bex-activator is ~150 lines of Go. It receives traffic for sleeping apps, touches `annotLastActive`, bumps `Deployment.spec.replicas = 1`, and returns 503 Retry-After. The operator reconcile (triggered by the Deployment change) switches the Ingress back.
