Xeonr Developer Docs

Warm pools

Pre-warmed, identity-free, single-shot pods for latency-sensitive job lanes.

Cold-starting a pod costs seconds. When a job is on a synchronous request path — a codegen plugin behind an SDK build, say — that's the whole latency budget. A warm pool keeps idle pods ready in a lane and claims one at dispatch.

Configure a lane

A lane is keyed by an environment.

await cp.raw.pool.configurePool({
  lane: "fer/protoc-gen-go:v1.34.2",
  namespace: "my-app",
  environmentId: environment,
  minIdle: 2,
  max: 10,
  resources: { cpuMillis: 500, memoryMb: 512 },
});

Pools are reached through cp.raw — the SDK does not model them, because the one consumer that uses them drives them from its own scheduler and gains nothing from a facade.

Then route work at it:

await cp.jobs.run({ environment, argv, poolLane: "fer/protoc-gen-go:v1.34.2" });

An empty lane spills to an ordinary cold start, so pool_lane is always safe to set — it's an optimisation, never a dependency. DeletePool removes a lane; ListPools shows configured intent.

How claiming works

Pooled pods are identity-free while warm: no token, no egress binding, no workspace. Identity is delivered at claim time over the agent channel that's already open.

A claimed pod serves exactly one job and is then destroyed. That single-shot rule is the answer to cross-job contamination: no pod, volume or filesystem is ever reused across jobs, so a job cannot leave anything behind for the next one to find. Claims are atomic, so two dispatchers racing for the last idle pod can't both win.

Because argv is delivered at claim rather than baked into the warm pod, a lane serves any command on its environment.

Demand signals

A pool's reconciler runs an EWMA predictor over recent claims. If you have leading indicators the platform can't see — a commit landing, a dashboard loading, a build starting — publish them and the pool warms ahead of the work:

await cp.raw.pool.publishDemandSignal({ lane: "fer/protoc-gen-go:v1.34.2", weight: 3 });

Observing

GetPoolState returns cumulative counters plus per-lane gauges:

FieldMeaning
pods_created / pods_deleted / create_errorsReconciler activity
claims_totalJobs served from a pool
spills_totalDispatches that found no idle pod and cold-started
attach_errorsFailed claims
lanes[]Per lane: idle, busy, target
create_latency_ewma_secThe predictor's pod-create latency estimate

A rising spills_total against a steady claims_total means min_idle is too low for the arrival rate. Idle warm pods are partitioned by priority class in the namespace quota, so they cannot starve real jobs.

On this page