Scaling and Health
Vertical scaling
Change an app's CPU and memory by moving it to another compute tier:
curl -u "$USER:$PASS" -X POST \
https://api.foundrydb.com/app-services/{id}/scale \
-H "Content-Type: application/json" \
-d '{ "plan_name": "tier-4" }'
The app moves through PendingModification before returning to Running. Storage size is not changed by a scale operation.
The diagram above shows both resize paths and the online storage grow. The reachability timeline strip makes the key difference visible: a hot resize keeps the strip solid green throughout, while a cold resize produces a brief red band during the VM reboot before the serving address is restored.
Hot vs cold resize
| Direction | Method | Downtime |
|---|---|---|
Up (e.g. tier-2 to tier-4) | Hot resize: plan changes on the running VM, CPU and memory hotplugged. | None. A tier-2 to tier-4 resize typically completes in under 10 seconds with the app reachable throughout. |
Down (e.g. tier-4 to tier-2) | Cold resize: VM restarts on the smaller plan. | Brief outage while the VM reboots. |
The app's floating IP persists across reboots via a boot-time systemd unit, so a cold resize does not change the app's address or require a DNS update.
Prefer tier-2, tier-4, and tier-6 for clean resizes. Tiers whose core and memory combination does not map cleanly to a standard cloud plan (tier-1, tier-3, tier-5) may overshoot cores on resize.
Storage expansion
Storage size can be increased independently of the compute plan, and is always online with no downtime:
curl -u "$USER:$PASS" -X PATCH \
https://api.foundrydb.com/app-services/{id} \
-H "Content-Type: application/json" \
-d '{ "storage_size_gb": 200 }'
Storage can only grow, never shrink. The request is applied to the attached data disk while the app continues to serve traffic. The new capacity is available to the running container immediately after the operation completes.
Health checks
Health checks serve two purposes:
- Deploy gate. During a blue/green redeploy, the platform probes the new container on
health_check_pathbefore cutting traffic over. A container that never goes healthy fails the deploy; the previous container keeps serving. - Availability alerts. The agent continuously monitors the running container and reports availability metrics. See Alerts below.
Configure the probe in app_config:
| Field | Default | Description |
|---|---|---|
health_check_path | / | HTTP path probed on the container's own port. Must return 2xx. |
health_check_interval_seconds | 2 | Seconds between probe attempts during a deploy. |
health_check_timeout_seconds | 120 | Maximum seconds to wait for the container to become healthy before the deploy fails. |
health_check_healthy_threshold | 1 | Consecutive 2xx responses required before the deploy cuts traffic over. |
The probe runs on the VM loopback against the container port. It does not depend on public DNS or TLS.
How the health check gates a deploy
During a blue/green deploy the platform starts the new (green) container alongside the existing (blue) container. The agent polls http://127.0.0.1:{port}{health_check_path} every health_check_interval_seconds. Once health_check_healthy_threshold consecutive 2xx responses are received, Caddy cuts ingress from blue to green and blue is drained. If health_check_timeout_seconds elapses without the threshold being met, the deploy is aborted: the green container is removed and blue continues to serve.
This means the health check path must be reachable from within the VM on the container's port. Paths that require a signed cookie, a specific Host header, or an internal IP allowlist will fail the probe. Use a dedicated /health or /ready endpoint that returns 200 as soon as the process is ready to accept requests.
Raise health_check_threshold above 1 if your application has a warm-up period where it returns 2xx before it is truly ready (for example, before caches are populated or background workers have started). Requiring two or three consecutive successes filters out these transient passes.
Restart
Restart the app container without a full redeploy:
curl -u "$USER:$PASS" -X POST \
https://api.foundrydb.com/app-services/{id}/restart
Returns 202 Accepted with a task_id. The container is restarted by the systemd Quadlet unit. This is distinct from a blue/green redeploy: a restart stops and restarts the running container in place, so there is a brief interruption.
Use a restart when the container is misbehaving but the image has not changed (for example, after a configuration environment variable update that does not trigger a full redeploy, or to clear a stuck in-process cache). For image updates, trigger a full redeploy instead so the health check gate applies.
Alerts
App VMs report CPU, memory, and storage metrics, which the platform's alert rules evaluate the same way as database services. Two additional availability alerts fire for apps:
| Alert | Condition | Severity |
|---|---|---|
| App Down | The active container unit has not been running for 3 minutes. The 3-minute tolerance absorbs the brief blip of a blue/green rollout or a restart. | Critical |
| App Restart Loop | The container has restarted more than 2 times (warning) or more than 5 times (critical) since the last report, indicating a crash loop rather than a one-off restart. | Warning / Critical |
Alerts appear on the Alerts tab of the app detail page in the dashboard, where you can acknowledge and resolve them.
Interpreting App Down
The App Down alert fires only after 3 minutes of the container unit being absent. This window is intentional: a blue/green cutover where blue drains and green starts takes a few seconds, and a cold resize reboot typically completes in under a minute. Neither of these should fire App Down.
If App Down fires, the container has not started (or has exited and the systemd unit has not restarted it). Check the container logs via the API or the dashboard Logs tab to identify the failure reason before restarting.
Interpreting App Restart Loop
The App Restart Loop alert compares the container restart count between heartbeat reports. A single restart (for example, a one-time OOM kill) produces a warning if it happens more than twice in one reporting period. Five or more restarts in one period indicates a crash loop.
Common causes of a crash loop:
- The process exits immediately on startup due to a missing environment variable or a failed database connection.
- The container runs out of memory and is killed by the kernel OOM killer repeatedly.
- A health check path is configured that the process cannot serve, causing Caddy to route traffic to an unready container that promptly crashes.
Increase the compute plan if the issue is memory pressure. Review container logs for startup errors if the issue is a configuration or dependency problem.