H
Hostess

Configure Autoscaling

Scale a service between a minimum and maximum number of instances, including all the way down to zero while it is idle

Autoscaling automatically adjusts the number of running instances (replicas) of your service. When traffic spikes, Hostess adds more replicas to handle the load. When traffic drops, it scales back down — to a floor you choose, or all the way to zero for services you opt in.

This guide covers how to configure autoscaling in hostess.yml, how to let an idle service drop to zero instances and wake on the next request, and how to choose the right settings for your service type.


Scaling Modes

ModeConfigBest For
Fixed replicasreplicas: 3Predictable services, background workers, services with consistent load
Autoscalingreplicas: { min: 2, max: 10, target_cpu: 70 }Variable traffic, APIs, web frontends, anything with unpredictable load
Scale to zeroreplicas: { min: 0, max: 3 }Side projects, demos, docs and preview apps that sit idle between visits

Default behavior: If you don't specify replicas at all, Hostess runs 1 replica with no autoscaling. type: static defaults to { min: 0, max: 1 } and sleeps when idle.


Configure Fixed Replicas

For services with predictable, steady load, use a fixed replica count:

hostess.yml
services:
  worker:
    type: custom
    image: myorg/worker:latest
    replicas: 3

This always runs exactly 3 instances of the service, regardless of CPU usage. Fixed replicas are useful for:

  • Background job workers that process a queue
  • Cron-triggered services
  • Services where you want full control over instance count
  • Development and staging environments where cost matters more than elasticity

Configure Autoscaling

For services with variable traffic, configure autoscaling with minimum and maximum replica counts and a CPU target:

hostess.yml
services:
  api:
    type: fastapi
    build:
      source: ./backend
    replicas:
      min: 2
      max: 10
      target_cpu: 70
    resources: medium

What each field means

FieldDescriptionExample
minMinimum number of replicas. Hostess never scales below this, even at zero traffic. Set 0 to let the service go idle at zero instances.2
maxMaximum number of replicas. Hostess never scales above this, even under extreme load. Always 1 or more.10
target_cpuTarget average CPU utilization percentage across all replicas. Applies when min is 1 or more.70

How target_cpu works

The target_cpu value is the average CPU utilization percentage that Hostess tries to maintain across all replicas of your service.

  • If the average CPU across all replicas exceeds target_cpu, Hostess adds more replicas
  • If the average CPU drops well below target_cpu, Hostess removes replicas (down to min)
  • The default is 70 if not specified

Example: You have target_cpu: 70 with 2 replicas, each using 90% CPU. The average is 90%, which exceeds 70%, so Hostess scales up to 3 (or more) replicas to bring the average down.

target_cpu is the scaling signal whenever min is 1 or more. Services that set min: 0 scale on incoming request load instead — see Scale to Zero While Idle.

Hostess manages stabilization windows and cooldown periods internally to prevent rapid scale-up/scale-down cycles (thrashing). You do not need to configure these manually.


Scale to Zero While Idle

Set min: 0 and your service releases every instance after about five minutes without requests. Its URLs stay live, and the next request wakes it automatically:

hostess.yml
version: "1.0"

services:
  database:
    type: postgres
    resources:
      preset: small
      storage: 10Gi

  web:
    type: nextjs
    build:
      source: ./web
    depends_on: [database]
    env:
      DATABASE_URL: ${database.url}
    replicas:
      min: 0
      max: 3

What you see

WhenWhat happens
No requests for about 5 minutesThe service drops to 0 instances. Its URLs keep working.
First request after idleHostess starts an instance and holds that request until the service is ready (up to 60 seconds), then returns the response.
Steady trafficNormal response times. The service scales between 1 and max on incoming request load.
Traffic stops againBack to 0 instances after about five minutes.

Only the first request after an idle stretch waits. Every request after it is served at full speed until the service goes idle again.

Which services can scale to zero

nextjs, fastapi, static, and custom services without persistent storage can set min: 0 in either of these shapes:

  • Public or team URL — exactly one public or team port. Visitors wake the service through its Hostess URL, custom domain, or preview URL. Add as many private ports as you like (for example a metrics port).
  • Private only — no public or team port. Another service or job wakes it with ${name.url}. The first port listed is the one that wakes the service. nextjs, fastapi, and static use their usual default ports when you omit ports:; a private custom service declares the port it listens on under ports:.

nextjs and static are public by default. fastapi and custom are private by default, and hence min: 0 is the default choice for those. type: static already sleeps by default.

Managed postgres and redis services, and custom services with persistence or retention: permanent, run continuously on a fixed instance count — so a service that just woke up finds its database and its data ready.

Private API plus public UI

Keep the API private and let both sides sleep; the UI wakes the API through ${api.url}:

hostess.yml
version: "1.0"

services:
  api:
    type: fastapi
    build:
      source: ./backend
    replicas:
      min: 0
      max: 2

  ui:
    type: nextjs
    build:
      source: ./web
    depends_on: [api]
    env:
      API_URL: ${api.url}
    replicas:
      min: 0
      max: 2

Call it from another service

Reach a scale-to-zero service with ${name.url} and the call wakes it, exactly like a visitor's request:

hostess.yml
  web:
    env:
      API_BASE: ${api.url}   # wakes api if it is idle

Use ${name.url} whenever any environment may scale the target to zero. ${name.host} and ${name.port} name the service's own listening address and are for always-on services like postgres and redis.

Sleep in preview, stay warm in production

Override replicas per environment so preview apps idle between reviews while production keeps a steady instance count. See Environments for more information.

hostess.yml
services:
  web:
    type: nextjs
    replicas:
      min: 0
      max: 2

environments:
  production:
    services:
      web:
        replicas: 1

Custom domains, previews, and deploys

  • Custom domains wake an idle public or team service exactly the way its Hostess URL does.
  • Preview environments inherit service-level min: 0, or use a per-environment override as above.
  • visibility: team services still sign the visitor in first; the request wakes the service after that.
  • Deploys stay strict. Hostess marks a deployment successful only after the new version starts and reports healthy, so a broken build fails the deploy instead of idling at zero. Idle scale-down begins after that.

Want the URL to always answer instantly? Use min: 1 to keep one instance warm and let target_cpu handle the rest.


Different service types have different scaling characteristics. Use these as starting points and adjust based on your actual traffic patterns:

API services (FastAPI, Express, Django, Flask)

API services typically handle many concurrent requests and benefit from aggressive scaling:

hostess.yml
services:
  api:
    type: fastapi
    build:
      source: ./backend
    replicas:
      min: 2
      max: 10
      target_cpu: 70
    resources: medium
  • min: 2 — Always have at least 2 replicas for redundancy (if one crashes, the other handles traffic)
  • max: 10-20 — Set based on your expected peak traffic
  • target_cpu: 70 — Scale up before CPUs are fully saturated, leaving headroom for traffic bursts

Frontend services (Next.js, static sites)

Frontends often have bursty traffic patterns (marketing launches, social media spikes):

hostess.yml
services:
  frontend:
    type: nextjs
    build:
      source: ./frontend
    replicas:
      min: 2
      max: 20
      target_cpu: 60
    resources: small
  • min: 2 — Redundancy for zero-downtime deploys
  • max: 20 — Higher ceiling for traffic spikes (frontend replicas are lightweight)
  • target_cpu: 60 — Lower target to scale up earlier since SSR can be CPU-intensive

Static file servers

type: static already defaults to { min: 0, max: 1 } and sleeps when idle. Pin a warm replica in any environment with environments.<env>.services.<name>.replicas: 1. See Static.

Background workers

Workers that process jobs from a queue have different scaling needs:

hostess.yml
services:
  worker:
    type: custom
    image: myorg/worker:latest
    replicas:
      min: 1
      max: 5
      target_cpu: 80
    resources: medium
  • min: 1 — A single worker can handle low-traffic periods
  • max: 5 — Scale up as queue depth increases (which drives CPU usage up)
  • target_cpu: 80 — Workers can run hotter since they are not latency-sensitive

Full-stack example

Here is a complete configuration with different scaling for each service type:

hostess.yml
version: "1.0"

services:
  database:
    type: postgres
    resources:
      preset: large
      storage: 50Gi

  cache:
    type: redis
    resources: medium

  api:
    type: fastapi
    build:
      source: ./backend
    depends_on: [database, cache]
    env:
      DATABASE_URL: ${database.url}
      REDIS_URL: ${cache.url}
    replicas:
      min: 2
      max: 10
      target_cpu: 70
    resources: medium

  frontend:
    type: nextjs
    build:
      source: ./frontend
    depends_on: [api]
    env:
      NEXT_PUBLIC_API_URL: ${api.external_url}
    replicas:
      min: 2
      max: 20
      target_cpu: 60
    resources: small

  worker:
    type: custom
    build:
      source: ./worker
    depends_on: [database, cache]
    env:
      DATABASE_URL: ${database.url}
      REDIS_URL: ${cache.url}
    replicas:
      min: 1
      max: 5
      target_cpu: 80
    resources: medium

Choosing the Right Resource Preset

Autoscaling works best when paired with the right resource allocation. If your resource preset is too small, CPU will spike quickly, causing unnecessary scaling. If it's too large, you're paying for unused capacity.

PresetCPUMemoryTypical Use
small0.5 cores512MiLightweight services, dev environments
medium1.0 core1GiProduction APIs, standard services
large2.0 cores2GiHigh-traffic services, CPU-intensive work
xlarge4.0 cores4GiHeavy processing, ML inference

Tip: Start with medium and monitor CPU usage. If your replicas consistently run below 30% CPU, consider using small. If they frequently hit 90%+ and scale up often, consider large.


Monitoring and Adjusting

After deploying with autoscaling, monitor your service's behavior in Hostess Studio:

  • Current replicas: How many instances are running right now
  • CPU utilization: Average CPU percentage across all replicas
  • Scaling events: When and why replicas were added or removed

Signs you need to adjust

SymptomAction
Constantly at max replicasIncrease max or upgrade to a larger resource preset
Frequent scale-up/scale-downIncrease min or lower target_cpu to stabilize
Never scales above minYour min may be too high, or target_cpu too low
Latency spikes before scalingLower target_cpu (e.g., from 70 to 60) to scale up earlier
The first visit after a quiet period feels slowExpected with min: 0; set min: 1 to keep one instance warm

Important Notes

Managed databases and persistent services run on a fixed instance count. Give postgres, redis, and custom services with persistence an explicit replicas: N, and size them with the resource preset that fits their workload.

  • target_cpu drives scaling when min is 1 or more, and defaults to 70% if you set min and max without it
  • min: 0 scales on incoming request load instead — see Scale to Zero While Idle
  • max is always 1 or more
  • Setting min equal to max holds a steady instance count (same as fixed replicas)
  • Override replicas per environment with environments.<env>.services.<name>.replicas

On this page