API Reference
The controller exposes a gRPC service (ControllerService) on port 50051 (default). All RPCs are instrumented with OpenTelemetry.
Service: ControllerService
GetInstance
Get a ready instance for a function. If no ready instance exists, the controller assigns an unassigned pod.
rpc GetInstance(GetInstanceRequest) returns (GetInstanceResponse)
Request:
| Field | Type | Number | Description |
|---|---|---|---|
function |
Function | 1 | Function to get an instance for. |
exclude_instance_names |
repeated string | 2 | Instance names to exclude; used by routers retrying after a failed dial. |
Response:
| Field | Type | Number | Description |
|---|---|---|---|
instance |
Instance | 1 | Assigned, ready instance. |
Behavior:
- For regular functions: returns an existing ready instance or assigns a new pod and scales to 1
- For oneshot functions: always assigns a fresh pod
- Excludes instances by name (useful when retrying after a failed dial)
Heartbeat
Send heartbeat signals for active functions. Heartbeats prevent function timeout and inform scaling decisions.
rpc Heartbeat(HeartbeatRequest) returns (HeartbeatResponse)
Request:
| Field | Type | Number | Description |
|---|---|---|---|
router_ip |
string | 1 | IP of the router sending the heartbeat batch. |
heartbeats |
repeated Heartbeat | 2 | One heartbeat per function with active in-flight requests. |
forwarded_for |
repeated string | 3 | Controller IPs that have already processed this batch; used to break forwarding cycles. |
Response: Empty.
Behavior:
- Updates per-router heartbeat state for each function
- Forwards to other controllers in the ring (excluding those in the
forwarded_forchain)
Scale
Scale a function to a desired number of instances.
rpc Scale(ScaleRequest) returns (ScaleResponse)
Request:
| Field | Type | Number | Description |
|---|---|---|---|
function |
Function | 1 | Function being scaled. |
desired_instances |
uint32 | 2 | Target ready-instance count after scaling. |
reason |
ScaleReason | 3 | Reason the scale was triggered. |
Response:
| Field | Type | Number | Description |
|---|---|---|---|
instances |
repeated Instance | 1 | Ready instances after the scale decision was applied. |
Behavior:
- Delegates to the responsible controller if not local
- Returns current ready instances after applying the scale decision
ReleaseInstance
Release (delete) a pod. Used by routers after oneshot requests complete.
rpc ReleaseInstance(ReleaseInstanceRequest) returns (ReleaseInstanceResponse)
Request:
| Field | Type | Number | Description |
|---|---|---|---|
instance |
Instance | 1 | Instance to release. |
Response: Empty.
Behavior:
- Deletes the pod (idempotent -- returns success even if the pod does not exist)
GetClusterState
Return a snapshot of the cluster's current state -- supervisors, recent events, and active configuration. Used by the web UI and operator tooling.
rpc GetClusterState(GetClusterStateRequest) returns (GetClusterStateResponse)
Request: Empty.
Response:
| Field | Type | Number | Description |
|---|---|---|---|
cluster_state |
ClusterState | 1 | Snapshot of the cluster's current supervisor, event, and config state. |
Behavior:
- Aggregates state from every controller in the ring; each controller contributes the supervisors it owns
Types
Function
| Field | Type | Number | Description |
|---|---|---|---|
namespace |
string | 1 | Kubernetes namespace the function is scheduled in. |
deployment |
string | 2 | Source deployment label that supplies the pod pool. |
tenant |
string | 3 | Tenant identifier; combined with namespace, deployment, and oneshot to compute the function hash. |
metadata |
string | 4 | Opaque string passed verbatim to the assigned pod; not part of the function hash. |
scale |
Scale | 5 | Per-function scaling targets (min, max, CPU, memory, in-flight requests). |
oneshot |
bool | 6 | True if each request gets a fresh pod; assigned pods are released after the request completes. |
Identity is determined by namespace + deployment + tenant + oneshot. Metadata and scale are excluded from the hash.
Scale
| Field | Type | Number | Description |
|---|---|---|---|
min_instances |
uint32 | 1 | Minimum ready-instance floor (0 enables scale-to-zero). |
max_instances |
uint32 | 2 | Hard ceiling on ready instances. |
target_cpu_usage_milli |
uint32 | 3 | Per-instance CPU target in millicores; the controller scales toward this average. |
target_memory_usage_mib |
uint32 | 4 | Per-instance memory target in mebibytes. |
target_in_flight_requests |
uint32 | 5 | Per-instance in-flight-request target. |
Instance
| Field | Type | Number | Description |
|---|---|---|---|
function |
Function | 1 | Function this instance is assigned to. |
name |
string | 2 | Pod name in the cluster. |
addr |
string | 3 | Backend address (host:port) the router proxies to. |
replica_set |
string | 4 | Owning ReplicaSet name; used to detect stale instances after a rollout. |
assigned_at |
google.protobuf.Timestamp | 5 | When the controller atomically claimed the pod for this function. |
ready_at |
google.protobuf.Timestamp | 6 | When the pod confirmed assignment via /__skipper/assign and started serving traffic. |
cpu_usage_milli |
uint32 | 7 | Most recent CPU usage sample in millicores. |
memory_usage_mib |
uint32 | 8 | Most recent memory usage sample in mebibytes. |
Heartbeat
| Field | Type | Number | Description |
|---|---|---|---|
function |
Function | 1 | Function the heartbeat is for. |
timestamp |
google.protobuf.Timestamp | 2 | Sender's clock reading at the time the batch was assembled. |
in_flight_requests |
uint32 | 3 | In-flight request count at the time the batch was assembled. |
ScaleReason
| Value | Number | Description |
|---|---|---|
SCALE_REASON_UNSPECIFIED |
0 | Default/unknown |
SCALE_REASON_CPU |
1 | CPU usage triggered scaling |
SCALE_REASON_HEARTBEAT_TIMEOUT |
2 | No heartbeat within timeout |
SCALE_REASON_IN_FLIGHT_REQUESTS |
3 | Request count triggered scaling |
SCALE_REASON_MEMORY |
4 | Memory usage triggered scaling |
SCALE_REASON_NO_READY_INSTANCES |
5 | No ready instances available |
Client configuration
Default retry policies for gRPC clients:
| Method | Max Attempts | Max Backoff | Retry On |
|---|---|---|---|
| GetInstance | 3 | 100ms | UNAVAILABLE |
| Heartbeat | 2 | 50ms | UNAVAILABLE |
| Scale | 3 | 500ms | UNAVAILABLE |
| ReleaseInstance | 2 | 50ms | UNAVAILABLE |
Connection uses the dns:/// scheme with round-robin load balancing for headless service discovery.