# How to Scale Apps in App Platform App Platform is a fully managed Platform-as-a-Service (PaaS) that deploys applications from Git repositories or container images. It automatically builds, deploys, and scales components while handling all underlying infrastructure. Scaling your app allows its infrastructure to match its workload. You can manually scale or [autoscale](#auto-scale) resources as demand changes. For example, if traffic spikes and performance slows, you can add containers to handle the increased load. There are two types of scaling: - **Horizontal scaling** adds or removes containers and distributes the workload across them. App Platform offers both fixed and automatic (autoscaling) options. - **Vertical scaling** increases a container’s memory or CPU. App Platform only supports fixed vertical scaling, which must be configured manually in the [DigitalOcean Control Panel](https://cloud.digitalocean.com), API, or CLI. **Note**: App Platform scaling applies to runtime resources, such as containers, CPU, and memory used while your app is running. Build-time resources are managed separately. XL build resources (8 CPUs and 20 GiB of memory during builds) are now enabled by default for all apps and do not require configuration or scaling. Autoscaling automatically adds or removes containers based on workload. This is useful for apps with high but inconsistent traffic. Autoscaling monitors the average CPU usage across all containers. If usage exceeds the specified threshold, additional containers can be added. If usage falls below the threshold, containers can be removed. Traffic is distributed based on the number of requests each container is handling, not by CPU alone. This means a container may still receive new requests even if it’s near 100% CPU usage. To improve traffic distribution, consider increasing the minimum container count or lowering the CPU threshold to scale earlier. ## Scale an App Using the API or CLI You can scale an app to a fixed size or configure autoscaling for an app by updating the app’s spec and then submitting the updated spec via the app [update command](https://docs.digitalocean.com/reference/doctl/reference/apps/update/index.html.md) or [API endpoint](https://docs.digitalocean.com/reference/api/digitalocean/index.html.md#operation/apps_update) ### Scale App to a Fixed Size To scale an app to a fixed container size and number of containers, update the `instance_count` or `instance_size_slug` fields of the component in your [app’s spec](https://docs.digitalocean.com/products/app-platform/reference/app-spec/index.html.md) and then submit the new spec. You can set `instance_count` between 1 and 250. This limit applies to both fixed scaling and autoscaling. If you need more instances, consider using a larger instance size or [contact support](https://cloudsupport.digitalocean.com). ```text 1- environment_slug: node-js 2 git: 3 branch: main 4 repo_clone_url: https://github.com/digitalocean/sample-nodejs.git 5 http_port: 8080 6 instance_count: 2 7 instance_size_slug: apps-s-1vcpu-1gb 8 name: sample-nodejs 9 run_command: yarn start 10 source_dir: / ``` ### Configure Autoscaling To configure autoscaling, add the `autoscaling` object to the app’s spec and then configure the following fields: - `min_instance_count`. The minimum number of containers the app can scale down to. Use a value of 1 or higher. - `max_instance_count`. The maximum number of containers the app can scale up to. Use a value up to 250. - `metrics`. This object contains the metrics that the app uses to determine whether to scale up or down. Currently, CPU usage is the only supported metric. For example, the following app’s scales a service component called “web” to a minimum of two containers and a maximum of five containers when the average CPU usage across the component’s containers exceeds or drops below 70%. ```text 1name: example-app 2services: 3- name: web 4 github: 5 repo: digitalocean/sample-golang 6 branch: master 7 autoscaling: 8 min_instance_count: 2 9 max_instance_count: 5 10 metrics: 11 cpu: 12 percent: 70 ``` ## How to Scale an App Using the DigitalOcean CLI 1. [Install `doctl`](https://docs.digitalocean.com/reference/doctl/how-to/install/index.html.md), the official DigitalOcean CLI. 2. [Create a personal access token](https://docs.digitalocean.com/reference/api/create-personal-access-token/index.html.md) and save it for use with `doctl`. 3. Use the token to grant `doctl` access to your DigitalOcean account. ```shell doctl auth init ``` 4. Finally, run `doctl apps update`. Basic usage looks like this, but you can [read the usage docs](https://docs.digitalocean.com/reference/doctl/reference/apps/update/index.html.md) for more details: ```shell doctl apps update [flags] ``` The following example updates an app with the ID `f81d4fae-7dec-11d0-a765-00a0c91e6bf6` using an app spec located in a directory called `/src/your-app.yaml`. Additionally, the command returns the updated app’s ID, ingress information, and creation date: ```shell doctl apps update f81d4fae-7dec-11d0-a765-00a0c91e6bf6 --spec src/your-app.yaml --format ID,DefaultIngress,Created ``` ## How to Scale an App Using the DigitalOcean API 1. [Create a personal access token](https://docs.digitalocean.com/reference/api/create-personal-access-token/index.html.md) and save it for use with the API. 2. Send a PUT request to [`https://api.digitalocean.com/v2/apps/{id}`](https://docs.digitalocean.com/reference/api/digitalocean//index.html.md#operation/apps_update). ### cURL Using cURL: ```shell curl -X PUT \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ "https://api.digitalocean.com/v2/apps/{id}" \ -d '{"alerts":[{"rule":"DEPLOYMENT_FAILED"},{"rule":"DOMAIN_FAILED"}],"domains":[{"domain":"example.com","type":"PRIMARY","zone":"example.com"}],"envs":[{"key":"API_KEY","scope":"RUN_AND_BUILD_TIME","type":"SECRET","value":"EV[1:zqiRIeaaYK/NqctZDYzy6t0pTrtRDez8:wqGpZRrsKN5nPhWQrS479cfBiXT0WQ==]"}],"features":["buildpack-stack=ubuntu-22"],"ingress":{},"name":"example-app","region":"nyc","services":[{"autoscaling":{"max_instance_count":4,"metrics":{"cpu":{"percent":70}},"min_instance_count":2},"git":{"branch":"main","repo_clone_url":"https://github.com/digitalocean/sample-nodejs.git"},"internal_ports":[8080],"log_destinations":[{"name":"your_log_consumer_name","open_search":{"endpoint":"logs.example.com:12345","basic_auth":{"user":"doadmin","password":"1234567890abcdef"},"index_name":"example-index","cluster_name":"example-cluster"}}],"name":"sample-nodejs","run_command":"yarn start","source_dir":"/"}]}' ``` ### Python Using [PyDo](https://github.com/digitalocean/pydo), the official DigitalOcean API client for Python: ```python import os from pydo import Client client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN")) req = { "spec": { "name": "web-app-01", "region": "nyc", "domains": [ { "domain": "app.example.com", "type": "DEFAULT", "wildcard": True, "zone": "example.com", "minimum_tls_version": "1.3", } ], "services": [], "static_sites": [ { "cors": { "allow_origins": [ {"exact": "https://www.example.com"}, {"regex": "^.*example.com"}, ], "allow_methods": [ "GET", "OPTIONS", "POST", "PUT", "PATCH", "DELETE", ], "allow_headers": ["Content-Type", "X-Custom-Header"], "expose_headers": ["Content-Encoding", "X-Custom-Header"], "max_age": "5h30m", "allow_credentials": False, }, "routes": [{"path": "/api", "preserve_path_prefix": True}], } ], "jobs": [ { "name": "api", "gitlab": { "branch": "main", "deploy_on_push": True, "repo": "digitalocean/sample-golang", }, "image": { "registry": "registry.hub.docker.com", "registry_type": "DOCR", "repository": "origin/master", "tag": "latest", }, "dockerfile_path": "path/to/Dockerfile", "build_command": "npm run build", "run_command": "bin/api", "source_dir": "path/to/dir", "envs": [ { "key": "BASE_URL", "scope": "BUILD_TIME", "type": "GENERAL", "value": "http://example.com", } ], "environment_slug": "node-js", "log_destinations": { "name": "my_log_destination", "papertrail": { "endpoint": "https://mypapertrailendpoint.com" }, "datadog": { "endpoint": "https://mydatadogendpoint.com", "api_key": "abcdefghijklmnopqrstuvwxyz0123456789", }, "logtail": { "token": "abcdefghijklmnopqrstuvwxyz0123456789" }, "open_search": { "endpoint": "https://myopensearchendpoint.com:9300" "index_name": "logs" "basic_auth": { "user": "doadmin", "password": "password" } }, }, "instance_count": 2, "instance_size_slug": "apps-s-1vcpu-0.5gb", "kind": "PRE_DEPLOY", } ], "workers": [ { "name": "api", "gitlab": { "branch": "main", "deploy_on_push": True, "repo": "digitalocean/sample-golang", }, "image": { "registry": "registry.hub.docker.com", "registry_type": "DOCR", "repository": "origin/master", "tag": "latest", }, "dockerfile_path": "path/to/Dockerfile", "build_command": "npm run build", "run_command": "bin/api", "source_dir": "path/to/dir", "envs": [ { "key": "BASE_URL", "scope": "BUILD_TIME", "type": "GENERAL", "value": "http://example.com", } ], "environment_slug": "node-js", "log_destinations": { "name": "my_log_destination", "papertrail": { "endpoint": "https://mypapertrailendpoint.com" }, "datadog": { "endpoint": "https://mydatadogendpoint.com", "api_key": "abcdefghijklmnopqrstuvwxyz0123456789", }, "logtail": { "token": "abcdefghijklmnopqrstuvwxyz0123456789" }, "open_search": { "endpoint": "https://myopensearchendpoint.com:9300" "index_name": "logs" "basic_auth": { "user": "doadmin", "password": "password" } }, }, "instance_count": 2, "instance_size_slug": "apps-s-1vcpu-0.5gb", } ], "functions": [ { "cors": { "allow_origins": [ {"exact": "https://www.example.com"}, {"regex": "^.*example.com"}, ], "allow_methods": [ "GET", "OPTIONS", "POST", "PUT", "PATCH", "DELETE", ], "allow_headers": ["Content-Type", "X-Custom-Header"], "expose_headers": ["Content-Encoding", "X-Custom-Header"], "max_age": "5h30m", "allow_credentials": False, }, "routes": [{"path": "/api", "preserve_path_prefix": True}], "name": "api", "source_dir": "path/to/dir", "alerts": [ { "rule": "CPU_UTILIZATION", "disabled": False, "operator": "GREATER_THAN", "value": 2.32, "window": "FIVE_MINUTES", } ], "envs": [ { "key": "BASE_URL", "scope": "BUILD_TIME", "type": "GENERAL", "value": "http://example.com", } ], "gitlab": { "branch": "main", "deploy_on_push": True, "repo": "digitalocean/sample-golang", }, "log_destinations": { "name": "my_log_destination", "papertrail": { "endpoint": "https://mypapertrailendpoint.com" }, "datadog": { "endpoint": "https://mydatadogendpoint.com", "api_key": "abcdefghijklmnopqrstuvwxyz0123456789", }, "logtail": { "token": "abcdefghijklmnopqrstuvwxyz0123456789" }, "open_search": { "endpoint": "https://myopensearchendpoint.com:9300" "index_name": "logs" "basic_auth": { "user": "doadmin", "password": "password" } }, }, } ], "databases": [ { "cluster_name": "cluster_name", "db_name": "my_db", "db_user": "superuser", "engine": "PG", "name": "prod-db", "production": True, "version": "12", } ], “vpc”: { “id”: “c22d8f48-4bc4-49f5-8ca0-58e7164427ac”, } } update_resp = client.apps.update(id="bb245ba", body=req) ``` ## Scale an App Using the Control Panel You can scale an app to a fixed size or configure autoscaling using the DigitalOcean Control Panel. ### Scale an App to a Fixed Size Using the Control Panel To scale an app to a fixed size, go to the [**Apps** page](https://cloud.digitalocean.com/apps), select your app, then click the **Settings** tab. Select the component you want to scale. In the **Resource Size** section, click **Edit**. In the **Containers** field, increase or decrease the number of containers as needed. ![The Resource Size section of the Settings page, showing the Containers field.](https://docs.digitalocean.com/screenshots/app-platform/fixed-scaling.91c802733be5c4d52f81a4bb0e4505565d0b16048a8cad327ef3dd340da0fc20.png) When finished, click **Save**. The app redeploys with the updated configuration. ### Configure Autoscaling for an App Using the Control Panel To configure autoscaling for an existing app, go to the [**Apps** page](https://cloud.digitalocean.com/apps), select your app, then click the **Settings** tab. Select the component you want to configure autoscaling for. In the **Resource Size** section, click **Edit**. Autoscaling is only available for apps with a dedicated CPU plan. If your app isn’t using one, select the **Instance size** menu, choose a dedicated CPU plan, and then click **Set containers to autoscale**. This opens the autoscaling settings: - **Minimum Containers**: The minimum number of containers the app can scale down to. - **Maximum Containers**: The maximum number of containers the app can scale up to. - **CPU Threshold**: The average CPU usage across all running containers that triggers scaling. ![The Resource Size section of the Settings page, showing the autoscaling options.](https://docs.digitalocean.com/screenshots/app-platform/autoscaling.c49cdf81077b6b1ca319be7891b951775002fe545181285cce8ff26d224443ca.png) Set your autoscaling parameters. The estimated **Monthly App Cost** updates and displays a range based on the app running at its minimum number and maximum number of containers for a full month. When finished, click **Save**. This automatically triggers a redeployment if necessary.