Skip to content

Processes and Scaling

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.

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

PatternRoutingCommon use
web, *-webPublic HTTP/WebSocket with managed TLSMain app, admin UI, public API
*-tcpPrivate TCP, reachable only by trusted appsInternal gRPC, RPC, internal APIs
*-rtcPublic UDP via per-process TURN gatewayWebRTC, SFUs, voice agents
release, *-releaseRuns once per deploy, before rolloutMigrations, one-time per-release setup
Anything else (e.g. worker)Not reachable from the networkBackground 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 for *-tcp and Real-Time and WebRTC for *-rtc.

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

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:

Terminal window
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.

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
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.

Terminal window
watasu pods --app my-app

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

Terminal window
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.

Terminal window
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 for the full table, rates, and ceilings.

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:

Terminal window
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:

Terminal window
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.

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 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