# Scaling

Container apps scale horizontally: identical instances are added under load and removed when it passes. Four settings under **Advanced** shape that behaviour. Static sites have none of them - the CDN scales by itself.

## How autoscaling decides

Two signals add instances:

- **Concurrency.** Each instance serves at most its concurrency in parallel requests; when demand exceeds what the running instances can carry, more are started.
- **CPU target.** When average CPU across instances crosses the target, an instance is added even if concurrency has headroom.

Instances are removed as traffic falls, down to the minimum. Watch it happen on the **Active instances** chart - see [Metrics](/platform/observability#metrics).

## Min instances

Instances kept running even with no traffic.

- **0** (the default): the app sleeps when idle and [stops billing](/billing/billing#scale-to-zero). The first request after a quiet period pays a cold start - a few seconds while an instance boots.
- **1 or more**: that many instances stay warm around the clock. No cold starts, billed while idle.

The Nano size can't stay warm - it always scales to zero. Pick a bigger size if you need a warm minimum.

**Example:** `1` for an API whose first request must be fast.

> [!TIP]
> Scale to zero is what makes [preview environments](/platform/preview-environments) cheap: a preview nobody is looking at costs nothing. Keep previews at 0 and raise only production if cold starts hurt.

## Max instances

The autoscaling ceiling. However hard traffic spikes, you never run - or pay for - more than this many instances at once. The default ceiling is 10; choices go up to 100, and your plan sets an upper bound for the ceiling itself.

**Example:** `10`

## Concurrency

How many requests a single instance handles at the same time (default `80`).

Higher means fewer instances for the same traffic - cheaper, but each request shares the instance's memory and CPU with more neighbours. Lower gives each request more headroom; CPU-heavy or memory-hungry endpoints often want `10`-`20`.

Each [size](/create/application-settings#size) has its own maximum:

| Size | Max concurrency |
| --- | --- |
| Nano | 40 |
| Micro | 80 |
| Small | 100 |
| Medium | 200 |
| Large | 300 |

**Example:** `80` for a typical I/O-bound API.

## CPU target

A new instance is added once average CPU across instances crosses this percentage (default `80%`).

A higher target runs instances hotter before scaling out - cheaper, with less headroom for sudden spikes. A lower target scales earlier and absorbs bursts more smoothly.

**Example:** `70` for spiky traffic; `85` to squeeze cost on steady load.

## Cold starts

An app at zero instances boots one on the first request: the image starts, your server begins listening on its [port](/create/build-settings#port), and the request is served. That is typically a few seconds, and it depends on your app - a lean server image cold-starts faster than one that loads heavy dependencies at startup.

Ways to spend it down:

- Set min instances to `1` on the environments where it matters (usually just production).
- Keep startup work lazy: connect to the [database](/platform/databases/connect) on first use rather than at boot.
- Keep the image lean - see [Deploy with a Dockerfile](/platform/frameworks/docker) for image-size advice.

## The SSR policy

Server-rendered frontends - Next.js, Nuxt, SvelteKit, Remix, Astro in SSR mode - have their shape pinned platform-wide: **Micro size, scale 0-3, tier-1 region**, always behind the edge CDN. The edge serves your audience; the origin only renders cache misses, so scaling knobs are hidden for these apps and the concurrency/CPU settings don't apply.

## Related

- [Application settings](/create/application-settings): Sizes, regions, and what pins them.
- [Billing](/billing/billing): Instance-hours, scale to zero, and spending limits.
- [Observability](/platform/observability): The charts that show scaling working.
- [Limits](/reference/limits): Every scaling number in one table.
