Compose Service Autoscaling
Automatically scale a Swarm stack service's replica count from live CPU/memory usage (self-hosted only).
Compose service autoscaling is self-hosted only, and only for compose stacks deployed to Swarm.
Requirements
- The compose service must be part of a stack (Swarm-deployed compose), not a plain Docker Compose deployment.
- Swarm Monitoring must be enabled for the organization — autoscaling reads the same per-replica CPU/memory samples.
- The runtime swarm service (
${appName}_${serviceName}) must be a replicated service; global or job-mode services are skipped.
Configure
Open the compose stack's Advanced tab. The Autoscaling card appears once both requirements above are met. Pick a service, then set:
- Enable autoscaling — while on, the replica count is managed automatically; manual replica changes made elsewhere are overridden on the next tick.
- Min / Max Replicas — defaults
2/15. - CPU Scale-Up (%) / CPU Scale-Down (%) — defaults
85/25. - Memory Scale-Up (%) / Memory Scale-Down (%) — defaults
85/25.
sustainedChecks (default 3), cooldownMinutes (default 5), and
stepSize (default 1) aren't exposed in this form — they use their
defaults unless set through the API directly (see below).
Reading configs requires the autoscaler.read custom-role permission;
saving requires autoscaler.update. Both endpoints also verify the compose
stack belongs to your active organization.
Scale decision
A background tick runs every minute for every enabled (compose, service) config. It reads the average CPU/memory over the last 5 minutes and decides:
- Scale up by
stepSizereplicas (capped atmaxReplicas) when CPU is abovetargetCpuMaxor memory is abovetargetMemMax, sustained forsustainedChecksconsecutive ticks, andcooldownMinuteshas passed since the last scale action. - Scale down by
stepSizereplicas (floored atminReplicas) when CPU is belowtargetCpuMinand memory is belowtargetMemMin(memory is ignored for scale-down if it has no samples), and the cooldown has elapsed. - Otherwise — inside the dead-band between the min/max targets, still in cooldown, or already at a bound — nothing happens.
The service is scaled in place with a live docker service update, not a
full docker stack deploy, so the rest of the compose spec is untouched. The
resulting replica count is persisted and re-applied on the next real
docker stack deploy, so a redeploy doesn't clobber an autoscaled count. A
tick that finds no recent metrics, a missing service, or a scale error for one
service logs it and moves on — it never aborts the whole tick.
API
POST /api/trpc/autoscaler.list
POST /api/trpc/autoscaler.upsertlist returns every per-service config for a compose stack:
{ "composeId": "compose_123" }upsert creates or updates the config for one service:
{
"composeId": "compose_123",
"serviceName": "web",
"enabled": true,
"minReplicas": 2,
"maxReplicas": 10,
"targetCpuMax": 80,
"targetCpuMin": 20,
"targetMemMax": 80,
"targetMemMin": 20,
"sustainedChecks": 3,
"cooldownMinutes": 5,
"stepSize": 1
}All fields except composeId and serviceName are optional and patch only
what's provided. The API rejects a patch where minReplicas > maxReplicas,
targetCpuMin >= targetCpuMax, or targetMemMin >= targetMemMax (checked
only when both sides of a pair are present). minReplicas/maxReplicas
accept 1–100, the CPU/memory targets accept 1–100,
sustainedChecks accepts 1–60, cooldownMinutes accepts 0–1440, and
stepSize accepts 1–10. Each upsert is recorded in the organization audit
log as an autoscaler-config update.