Docs/ Infraestrutura/ Escalonamento

Escalonamento

Réplicas, limites de CPU e memória e escalonamento automático de um app, no servidor que o executa.

O que exige licença

Definir você mesmo as réplicas e os limites na sua própria máquina está disponível em todos os planos. Só a automação exige licença:

RecursoPlano
Número de réplicas manual (sh0 scale, POST …/scale)Todos os planos
Limites de CPU e memória (PUT …/resources)Todos os planos
Escalonamento automático (criar uma configuração, ativá-la, um mínimo ou máximo acima de 1)Business
A aba Escalonamento do painelExibida só com licença Business; nos outros planos, use a CLI ou a API

Escalonamento manual

sh0 scale <app> <réplicas> inicia ou para contêineres para que o app rode com o número de réplicas pedido; --status mostra a configuração (saída real):

Terminal
$ sh0 scale my-api 2
my-api: scaled 1 -> 2 replica(s)

$ sh0 scale my-api --status
Scaling status for my-api:
  Current replicas:   2
  Min replicas:       1
  Max replicas:       1
  Autoscaling:        disabled
  CPU threshold:      80%
  Memory threshold:   80%
  LB policy:          round_robin
  Cooldown:           300s

Pela API:

Terminal
curl -X POST https://panel.example.com/api/v1/apps/<app-id>/scale \
  -H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
  -d '{"replicas":2}'

A API aceita de 1 a 50 réplicas; a CLI recusa mais de 10 (“Replicas must be between 1 and 10”). Escalonar exige o papel developer no projeto do app.

Limites de CPU e memória

Cada contêiner de app roda com uma cota de CPU e um limite de memória. Altere-os com PUT /api/v1/apps/<id>/resources (resposta real):

Terminal
$ curl -X PUT https://panel.example.com/api/v1/apps/<app-id>/resources \
    -H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
    -d '{"cpu_limit":500,"memory_limit":256}'
{"data":{"app_id":"<app-id>","autoscale_cpu_threshold":80,"autoscale_enabled":false,"autoscale_memory_threshold":80,"cooldown_seconds":300,"cpu_limit":500,"created_at":"2026-10-02 02:55:05","current_replicas":2,"id":"4930c97a-d6ab-44ac-bfd0-368d2c6ac4cd","last_scale_at":null,"lb_policy":"round_robin","max_replicas":1,"memory_limit":256,"min_replicas":1,"updated_at":"2026-10-02 02:55:05"}}
  • cpu_limit é em milicores (1000 = um núcleo), memory_limit em MB. Um campo omitido fica inalterado; 0 volta ao padrão.
  • Padrões quando nada é definido: 512 MB de memória e metade dos núcleos da máquina para a CPU (no mínimo 0,5 núcleo).
  • Os limites vêm da máquina: CPU de 100 milicores até o número de núcleos, memória de 64 MB até a RAM da máquina. Fora deles, o erro mostra os números reais, por exemplo:
  • Os novos limites valem para contêineres criados depois: reimplante o app para que o contêiner em execução os receba.
Response
{"error":{"code":"VALIDATION_ERROR","message":"memory_limit must be between 64 and 7751 MB (this machine has 7751 MB of RAM), or 0 to reset"}}

Escalonamento automático

Com licença Business, o sh0 ajusta o número de réplicas conforme o uso de CPU e memória. Crie a configuração uma vez:

Terminal
curl -X POST https://panel.example.com/api/v1/apps/<app-id>/scaling \
  -H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
  -d '{"min_replicas":1,"max_replicas":4,"target_cpu_percent":70,"target_memory_percent":80,"cooldown_seconds":300,"enabled":true}'
  • min_replicas, max_replicas -- de 1 a 50, máximo não inferior ao mínimo. Ambos valem 1 por padrão.
  • target_cpu_percent, target_memory_percent -- de 10 a 100, padrão 80.
  • cooldown_seconds -- de 60 a 3600, padrão 300: nenhuma nova ação antes desse prazo após a anterior.
  • lb_policy -- round_robin (padrão), least_conn ou random.
  • cpu_limit, memory_limit -- opcionais, mesmo sentido e mesmos limites acima.

Uma configuração já existe assim que limites são definidos, e um segundo POST é recusado (“Scaling config already exists for this app. Use PATCH to update.”). Altere-a com PATCH /api/v1/apps/<id>/scaling/update, com todos os campos opcionais. Sem licença Business, a recusa é um 403 com o código LICENSE_REQUIRED.

Warning
sh0 scale <app> --auto cria uma configuração de 1 a 3 réplicas. Se já existir uma configuração, ele apenas ativa o escalonamento automático e mantém os limites existentes: com máximo 1 (o valor deixado ao definir limites), nada vai escalar. Confira com --status e aumente max_replicas pela API.

Como o autoscaler decide

  • O autoscaler roda a cada 30 segundos (sh0 serve --autoscale-interval; 0 o desativa) e lê as métricas de CPU e memória do app dos últimos dois minutos.
  • Para cima quando a média de CPU ou a de memória passa da meta.
  • Para baixo quando as duas médias ficam abaixo da metade da meta, com pelo menos 10 amostras de cada.
  • Uma réplica por vez, dentro dos limites, e nunca durante o cooldown.
  • O plano é verificado a cada passagem: se a licença expirar, o escalonamento automático para.

Balanceamento de carga

Todas as réplicas ficam atrás dos mesmos domínios: o Caddy distribui as requisições entre elas conforme lb_policy. Na rede do projeto, o alias do app (my-api.internal) resolve para todas as réplicas.

Limitações

  • Um servidor. As réplicas rodam no servidor que hospeda o app; trazem paralelismo de CPU e resistência a falhas, não mais máquina.
  • Montagens. Réplicas adicionadas por sh0 scale iniciam sem os volumes montados do app. Não escalone um app que grava em volume.
  • Estado. Requisições de um mesmo usuário podem cair em réplicas diferentes: mantenha sessões e uploads fora do contêiner (banco de dados, Redis, armazenamento de objetos).
  • Bancos de dados. Servidores de banco de dados têm seus próprios ajustes de recursos; esta página trata de apps.