> ## Documentation Index
> Fetch the complete documentation index at: https://docs.slipway.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Scaling

> Run more than one copy of a service, at a fixed count or on demand.

A `web` or `worker` service can run several identical pods. Traffic to a web service is
load balanced across them.

There are two ways to do it, and a service uses one or the other. `replicas` fixes the
count. `scaling` lets slipway move the count between a floor and a ceiling based on
utilisation.

Scaling requires the Hobby plan or higher. See [Plans](/plans).

## A fixed number of replicas

**Console**

Open the service's **Scaling** tab and set the replica count.

**slipway.yaml**

```yaml slipway.yaml theme={"system"}
services:
  - name: api
    runtime: docker
    replicas: 3
    ports:
      - port: 3000
        public: true
```

`replicas` accepts 0 to 20. Setting it to 0 stops the service without tearing it down.

## Autoscaling

**Console**

On the **Scaling** tab, switch to autoscaling and set the minimum, the maximum, and a
utilisation target.

**slipway.yaml**

```yaml slipway.yaml theme={"system"}
services:
  - name: api
    runtime: docker
    cpu: 1
    memory: 1GB
    scaling:
      min: 2
      max: 10
      targetCPUPercent: 70
    ports:
      - port: 3000
        public: true
```

| Field | Range | Notes |
| - | - | - |
| `min` | 1 or more | The floor. The service never drops below this. |
| `max` | `min` or more, up to 20 | The ceiling. |
| `targetCPUPercent` | 0 to 100 | Average CPU utilisation to hold. |
| `targetMemoryPercent` | 0 to 100 | Average memory utilisation to hold. |

If you set neither target, slipway uses a CPU target of 70. Setting both makes the
autoscaler add pods when either metric is over its target.

> [!WARNING]
>
> A utilisation target is measured against the pod's CPU **request**, not its limit. Because
> CPU requests are a fraction of the configured limit, a service can sit above 100% of its
> request while still well below its limit. Set the target against observed behaviour rather
> than assuming it maps to the number on the Compute tab.

## Restrictions

**`replicas` and `scaling` are mutually exclusive.** Declare one.

**Neither works with a disk.** A disk is a single block device and cannot be mounted by
more than one pod, so `replicas` above 1 and `scaling` with a `max` above 1 are both
rejected on a service that declares `disk:`. See [Disks](/data/disks).

**Neither applies to `cron` or `static`.** A cron service materialises as a job per run,
and a static site has no pod.

## Billing

Each replica is billed at the service's full allocation. A service at 1 vCPU and 1 GiB
running three replicas costs three times what one replica costs, for as long as three are
running.

An autoscaled service is billed for the replicas actually running at each moment, not for
its ceiling. slipway reconciles the running count on a short interval so the metered
figure follows the real one.

## Autoscaling and sleep

Both decide how many replicas a service runs, so they cannot both be on. An autoscaler with
a floor of one would scale the service straight back up the moment sleep scaled it to zero.

If you turn on sleep for a service you have set to autoscale, slipway says no and asks you to
turn one of them off. A fixed replica count is fine alongside sleep: sleep drops to zero and
waking restores exactly that count.

On a plan that sleeps idle services for you, sleep wins and the service runs at one replica.
The deploy still goes through, and its timeline records that autoscaling was not applied.

## Application considerations

A service that runs more than one replica has to tolerate it:

* Any two requests from the same client can land on different pods, so session state
  belongs in Redis or a database rather than in process memory.
* Scheduled work inside the application runs once per pod. Move it to a
  [`cron` service](/services/overview#cron) so it runs once.
* In-process caches are per pod and will disagree with each other.
* Anything that writes to the local filesystem is per pod, and the filesystem is lost when
  the pod is replaced.

## Appendix: glossary

| Term | Meaning |
| - | - |
| Replica | One pod of a service. Every replica runs the same image with the same configuration. |
| Utilisation target | The average resource use the autoscaler tries to hold by adding or removing replicas. |
| Floor | The `min` replica count, below which the autoscaler will not go. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.