# Processes and Scaling

> Run multiple process types, scale replicas, and choose pod sizes. Covers web, workers, multiple public web entrypoints, private TCP services, RTC processes, and release processes.

Most production apps are more than one web process. Watasu treats every named process in your `Procfile` as a separately scalable workload, and the **name** decides what kind of routing it gets.

## What a process is

A process is one named workload inside an app. The process name carries meaning — Watasu reads the suffix to decide how to expose it:

| Pattern                       | Routing                                     | Common use                             |
| ----------------------------- | ------------------------------------------- | -------------------------------------- |
| `web`, `*-web`                | Public HTTP/WebSocket with managed TLS      | Main app, admin UI, public API         |
| `*-tcp`                       | Private TCP, reachable only by trusted apps | Internal gRPC, RPC, internal APIs      |
| `*-rtc`                       | Public UDP via per-process TURN gateway     | WebRTC, SFUs, voice agents             |
| `release`, `*-release`        | Runs once per deploy, before rollout        | Migrations, one-time per-release setup |
| Anything else (e.g. `worker`) | Not reachable from the network              | Background jobs, schedulers            |

So `web`, `admin-web`, `api-web`, `grpc-tcp`, `sfu-rtc`, `worker`, and `release` aren't naming conventions — they're the routing contract.

See [Private Networking](https://docs.watasu.io/apps/private-networking.md) for `*-tcp` and [Real-Time and WebRTC](https://docs.watasu.io/apps/realtime.md) for `*-rtc`.

## Multiple public web processes

You're not limited to one `web` process per app. Name additional public entrypoints with the `*-web` suffix and Watasu routes each one publicly:

```text
web:        bundle exec puma -C config/puma.rb
admin-web:  bundle exec puma -C config/admin_puma.rb
api-web:    bundle exec puma -C config/api_puma.rb
worker:     bundle exec sidekiq
```

Each `*-web` process gets its own managed `*.watasuhost.com` URL, scales independently, and can have its own custom domain attached:

```bash
watasu domains:add admin.example.com --process admin-web --app my-app
```

This is how you keep an admin surface, a public API, and your main app in one codebase without splitting into three deployments.

## The release process

A process named `release` runs **once per deploy, before the new release goes live**. Use it for:

* database migrations
* one-time per-release setup checks
* cache invalidation or priming
* assets compilation that can't happen in the build

```text
release: bundle exec rails db:migrate
web:     bundle exec puma
worker:  bundle exec sidekiq
```

A failing release process **aborts the deploy** — the new code never goes live. Keep release tasks fast and idempotent.

In apps with several independent surfaces, a process named `<group>-release` (like `admin-release`) gates only the processes sharing its prefix, while a plain `release` gates everything.

## Inspect the formation

```bash
watasu pods --app my-app
```

Shows each process type with its replica count, pod size, CPU/memory, and routing.

## Scale replicas

```bash
watasu pods:scale web=3 worker=1 --app my-app
```

Each process scales independently. Set a process to `0` to stop it without removing it from your `Procfile`.

## Change pod sizes

```bash
watasu pods:type web=standard-2x worker=dynamic-1x --app my-app
```

Available sizes include `hobby`, fixed-price `standard-1x` through `standard-16x`, and usage-billed `dynamic-1x` through `dynamic-16x`. Dynamic processes stay online but bill measured CPU and memory instead of the selected limit; Standard is cheaper for sustained use. `hobby` is capped at one replica, while Standard and Dynamic sizes can scale out. See [Pod Sizes](https://docs.watasu.io/reference/pod-sizes.md) for the full table, rates, and ceilings.

## Scale out vs. scale up

There are two levers and they solve different problems:

* **Scale out** (more replicas) when concurrency is the bottleneck — many short requests, parallel job consumption, fault tolerance.
* **Scale up** (bigger pods) when a single process is memory- or CPU-bound — large in-memory caches, single-threaded hot paths, image processing.

A common starting formation for a real app:

```bash
watasu pods:scale web=2 worker=1 --app my-app
watasu pods:type web=standard-1x worker=standard-1x --app my-app
```

Two `web` replicas give you redundancy. Worker is separate so a slow background job doesn't stall HTTP requests.

For an uneven workload, mix billing models instead of moving the whole app:

```bash
watasu pods:type web=standard-1x worker=dynamic-2x --app my-app
```

Here `web` keeps predictable fixed-price capacity while `worker` can burst to 2 vCPU and 4 GiB and bills its measured use.

## Multi-DC placement

Once a process is scaled to **2 or more replicas**, Watasu automatically spreads its replicas across separate eligible EU zones for resilience — no configuration needed. Each new release revision is spread independently during a rolling update, so the outgoing revision does not distort placement of the incoming one.

## Scaling is a runtime change

Scaling and pod-type changes are immediately applied to running pods. Treat them like deploys:

* change one thing at a time when you're debugging
* watch logs and metrics afterwards
* prefer additive changes (scale up first, scale old down second) for sensitive workloads

[View this page on the web](https://docs.watasu.io/apps/processes-and-scaling/)
