---
id: w3/m4/t002
title: "PrometheusResourceSource: cpu/memory/instance_count via query_range, percentage-of-limit mode"
worker: worker3
status: done
estimate: 45m
depends_on: [w3/m4/t001]
---

## Objective

Add a Prometheus-backed resource-metrics source that answers cpu/memory/instance_count as **stepped time series** over the requested range — the historical sibling of `NewResourceMetricsSource` (metrics-server snapshot), reusing the `query_range` plumbing `NewPrometheusRequestSource` already has.

## Context

- Sources live in `operator/internal/api/metricsource.go`; Core consumes them via injected interfaces so the domain layer stays client-free (`operator/internal/api/core.go`, `metrics.go`).
- Queries (per App, pods matched on the `app.bex.co/app=<name>` label carried into the `pod` label by t001's relabeling — adjust to the actual relabel output):
  - cpu: `rate(container_cpu_usage_seconds_total{...}[<step>])` per pod → cores.
  - memory: `container_memory_working_set_bytes{...}` per pod → bytes.
  - instance_count: `count(container_memory_working_set_bytes{...})` over time.
- `percentage=true`: divide by the pod-spec limit exactly as the metrics-server path does today (reuse the existing limit lookup — no kube-state-metrics).
- Honor `startTime`/`endTime`/`resolutionSeconds`; keep the per-series `instance`/`resource` labels the REST/GraphQL adapters already emit.

## Steps

1. Implement `NewPrometheusResourceSource` in `metricsource.go` satisfying the resource-metrics source interface, issuing `query_range` for the three metrics.
2. Map Prometheus matrices into the existing series/points domain types, preserving label conventions and units.
3. Wire the percentage-of-limit division through the existing pod-spec limit read.

## Files

- `operator/internal/api/metricsource.go`
- `operator/internal/api/metrics.go` (only if the source interface needs a range-aware signature)

## Acceptance criteria

- [ ] Unit test with a fake Prometheus HTTP endpoint: cpu/memory/instance_count return multi-point series honoring the requested range and step.
- [ ] `percentage=true` returns 0–100 values consistent with the pod limit.
- [ ] `make test` green.

## Out of scope

- Choosing between Prometheus and metrics-server at runtime (t003).
- GitOps/scrape config (t001).
