diff --git a/src/_posts/platform/app/scaling/2000-01-01-choosing-container-size.md b/src/_posts/platform/app/scaling/2000-01-01-choosing-container-size.md new file mode 100644 index 000000000..9db7bdd5a --- /dev/null +++ b/src/_posts/platform/app/scaling/2000-01-01-choosing-container-size.md @@ -0,0 +1,92 @@ +--- +title: Choosing a Container Size +nav: Choosing a Container Size +modified_at: 2026-05-18 00:00:00 +tags: app scaling containers memory metrics +index: 1 +--- + +Choosing the right container size is a balance between safety, performance, and +cost. Memory is often the resource that most directly constrains this choice +because each running container must stay below its own memory quota. A safe +initial size gives your application enough memory headroom while you collect +real metrics and validate the workload. + +For simple applications, the default `M` container size is often a reasonable +starting point. Choose a larger size from the beginning when you already know +that your application has higher memory needs, for example because it uses a +memory-intensive runtime, high concurrency, large in-memory datasets, caches, +background jobs processing large payloads, or unknown production traffic. + +See the [container sizes][container-sizes] page for the available sizes, memory +limits, and PID limits. + + +## Start Safe, Then Adjust + +When you are unsure about the right size, start with a size that gives your +application enough headroom. After deployment, use [metrics][metrics], +[alerts][alerts], and realistic load testing to adjust the size. + +Avoid choosing a smaller size only because the application starts successfully. +An application can boot with low memory usage and still consume much more +memory under real traffic, scheduled jobs, large requests, or specific user +flows. + +Before downsizing, validate that the application keeps enough memory headroom +below the limit over time. + + +## Validate With Metrics and Load Testing + +Before changing the container size, inspect the application charts in the +[Metrics tab][metrics]. Compare memory usage with the memory quota of the +selected container size, and also review CPU usage and application-level +signals. + +Pay attention to: + +- CPU usage. +- RAM and swap usage. +- Whether memory usage returns to a stable baseline after traffic peaks. +- Response time. +- 5xx errors. +- Restart events. + +If production metrics are not enough to validate a size, test the application +with realistic load and non-sensitive data. + +{% note %} +Before running intensive load tests against an application hosted on Scalingo, +read our [external testing procedures][external-testing]. +{% endnote %} + + +## Match Capacity to Traffic + +Once you have chosen the target size for each process type, use +[Scaling Your Application][scaling] to configure the expected capacity for your +traffic and workload. + +If the application is critical or you are unsure about the safest sizing +strategy, contact Scalingo support. + + +## Monitor Resource Usage + +Configure [alerts][alerts] for critical metrics, and keep +[notifiers][notifiers] configured so the right people receive notifications +before resource usage becomes critical. + +If the application consumes all its available memory, it can be terminated by +the system. See the [Runtime Issues][oom-diagnosis] page for Out of Memory +crash diagnosis and recovery guidance. + + +[alerts]: {% post_url platform/app/2000-01-01-alerts %} +[container-sizes]: {% post_url platform/internals/2000-01-01-container-sizes %} +[external-testing]: {% post_url security/procedures/2000-01-01-external-testing %}#can-i-run-a-load-test-on-my-application-that-is-running-on-scalingo +[metrics]: {% post_url platform/app/2000-01-01-metrics %} +[notifiers]: {% post_url platform/app/2000-01-01-notifiers %} +[oom-diagnosis]: {% post_url platform/app/troubleshooting/2000-01-01-runtime-issues %}#out-of-memory-crashes +[scaling]: {% post_url platform/app/scaling/2000-01-01-scaling %} diff --git a/src/_posts/platform/app/scaling/2000-01-01-optimizing-application-architecture.md b/src/_posts/platform/app/scaling/2000-01-01-optimizing-application-architecture.md new file mode 100644 index 000000000..5f6ad3d8b --- /dev/null +++ b/src/_posts/platform/app/scaling/2000-01-01-optimizing-application-architecture.md @@ -0,0 +1,128 @@ +--- +title: Optimizing Application Architecture +nav: Optimized Architecture +modified_at: 2026-05-18 00:00:00 +tags: app scaling architecture containers memory metrics performance concurrency +index: 5 +--- + +An optimized application architecture makes efficient use of the resources +allocated to each container while keeping the application easy to operate. On +Scalingo, this usually means separating workloads into [process types][procfile], +keeping web requests short, tuning concurrency carefully, and using metrics to +decide when to optimize code, split work, or scale the application. + +This page focuses on how to structure the application workload. To choose a +container size, see [Choosing a Container Size][choosing-container-size]. To +change the number or size of running containers, see +[Scaling Your Application][scaling]. + + +## Design Around Process Types + +Use [process types][procfile] to separate workloads that do not have the same +operational profile. A `web` process should handle HTTP requests and return +responses quickly. Background workers, schedulers, importers, exporters, and +other resource-intensive jobs should run in dedicated process types. + +Favor focused processes that can be scaled independently, with a clear role +and a predictable resource profile. This is usually easier to operate than a +single large process that handles every workload. + +This separation has several advantages: + +- each workload can have its own number of containers; +- each workload can use a container size adapted to its resource profile; +- focused containers can start and scale faster; +- long or heavy tasks do not block request handling; +- worker concurrency can be tuned independently from web concurrency; +- incidents are easier to diagnose from metrics and logs. + +Typical process types include: + +- `web` for HTTP traffic; +- `worker` for background jobs; +- `clock` or `scheduler` for recurring jobs; +- dedicated workers for heavy jobs such as PDF generation, image processing, + imports, exports, or batch tasks. + +For long tasks triggered by a user request, return quickly from the web process +and process the work asynchronously. See [Long Running Process][long-process] +for the general pattern. + + +## Tune Concurrency Carefully + +Concurrency lets a process handle more work in parallel, but each additional +thread, worker, or child process usually consumes more memory and may increase +database or external service pressure. + +Tune concurrency separately for each process type: + +- increase web concurrency only if response time and resource usage stay + healthy under realistic traffic; +- reduce worker concurrency if occasional jobs create memory pressure; +- keep enough database connections for the configured concurrency; +- use separate process types for jobs that have different resource profiles, + such as CPU-heavy and memory-heavy jobs. + +Some runtimes expose Scalingo-specific or buildpack-provided defaults and +environment variables. See the language pages for details: +[Ruby][ruby], [Python][python], [PHP][php], [Java][java], [Node.js][nodejs], +and [Go][go]. + + +## Handle Memory-Intensive Workloads + +Memory pressure is often caused by specific workloads rather than by every +request. Check whether the application consumes more memory regularly, or only +during occasional tasks such as: + +- background jobs; +- PDF generation; +- image or video processing; +- large imports or exports; +- report generation; +- scheduled batch tasks; +- large in-memory caches or datasets. + +Depending on what you observe, prefer the smallest change that addresses the +actual cause: + +- optimize the code path that allocates too much memory; +- tune runtime-specific memory settings; +- split heavy jobs into a dedicated process type; +- reduce worker or job concurrency; +- split large jobs into smaller chunks; +- isolate workloads that do not have the same resource profile. + +If each container still needs more memory after these changes, continue with +[Choosing a Container Size][choosing-container-size]. + + +## Size and Scale Your App + +Once your application is optimized for its workload: + +- [choose the right size][choosing-container-size] for each process type; +- [scale the application][scaling] to match capacity to traffic; +- read [Application Metrics][metrics] and configure [alerts][alerts] to monitor + the application after changes. + +If the application reaches its memory limit and crashes, see [Runtime +Issues][oom-diagnosis] for diagnosis and recovery guidance. + + +[alerts]: {% post_url platform/app/2000-01-01-alerts %} +[choosing-container-size]: {% post_url platform/app/scaling/2000-01-01-choosing-container-size %} +[go]: {% post_url languages/go/2000-01-01-start %} +[java]: {% post_url languages/java/2000-01-01-start %} +[long-process]: {% post_url platform/app/2000-01-01-long-process %} +[metrics]: {% post_url platform/app/2000-01-01-metrics %} +[nodejs]: {% post_url languages/nodejs/2000-01-01-start %} +[oom-diagnosis]: {% post_url platform/app/troubleshooting/2000-01-01-runtime-issues %}#out-of-memory-crashes +[php]: {% post_url languages/php/2000-01-01-start %} +[procfile]: {% post_url platform/app/2000-01-01-procfile %} +[python]: {% post_url languages/python/2000-01-01-start %} +[ruby]: {% post_url languages/ruby/2000-01-01-start %} +[scaling]: {% post_url platform/app/scaling/2000-01-01-scaling %} diff --git a/src/_posts/platform/app/scaling/2000-01-01-scaling.md b/src/_posts/platform/app/scaling/2000-01-01-scaling.md index da50929f0..41b4fd42c 100644 --- a/src/_posts/platform/app/scaling/2000-01-01-scaling.md +++ b/src/_posts/platform/app/scaling/2000-01-01-scaling.md @@ -1,7 +1,7 @@ --- title: Scaling Your Application nav: Scaling -modified_at: 2026-01-02 12:00:00 +modified_at: 2026-05-18 00:00:00 index: 10 --- @@ -62,22 +62,40 @@ application to traffic fluctuations. Here is a quick comparison table, in the context of a Platform as a Service: -| | Vertical Scaling | Horizontal Scaling | -| --------------- | --------------------------------------- | --------------------------------- | -| **Approach** | Enhancing individual instance capacity | Adding more instances | -| **Cost** | Can become expensive at higher limits | Often more cost-efficient | -| **Resilience** | Low (single point of failure) | High (distributed resources) | -| **Flexibility** | Low, limited by physical/virtual constraints | High, limited by the application architecture | -| **When** | Lack or overuse of CPU or RAM (swap increase or decrease) | Increase or decrease in total application traffic | +| | Vertical Scaling | Horizontal Scaling | +|-----------------|----------------------------------------------|---------------------------------------------------| +| **Approach** | Enhancing individual instance capacity | Adding more instances | +| **Cost** | Can become expensive at higher limits | Often more cost-efficient | +| **Resilience** | Low (single point of failure) | High (distributed resources) | +| **Flexibility** | Low, limited by physical/virtual constraints | High, limited by the application architecture | +| **When** | Lack or overuse of resources (CPU or RAM) | Increase or decrease in total application traffic | +### Memory Usage and Scaling Decisions -## Limitations +If your application is approaching its memory limit, check its +[memory metrics][metrics] and apply the same distinction between vertical and +horizontal scaling to the memory usage pattern. -- Vertical scaling is limited by the platform. The biggest container we can - currently boot is the `2XL` container, with 4GB of RAM. For a comprehensive - list of container sizes and corresponding specifications, please see our +Use vertical scaling when each container needs more memory to run safely. In +that case, choose a larger size with +[Choosing a Container Size][choosing-container-size]. Adding more containers +can help when memory usage increases because traffic increases and the workload +can be distributed across multiple containers. However, horizontal scaling will +not fix an application that individually requires more memory than the selected +container size provides. + +If memory pressure comes from specific jobs or high concurrency, first review +the application structure with +[Optimizing Application Architecture][optimizing-architecture]. + + +## Scaling Limits + +- Vertical scaling currently goes up to the `2XL` container size, with 4GB of + RAM. For a comprehensive list of container sizes and corresponding + specifications, please see our [dedicated documentation page]({% post_url platform/internals/2000-01-01-container-sizes %}). -- Horizontal scaling is limited by default to a maximum of 10 containers per +- Horizontal scaling is available by default up to 10 containers per [process type]({% post_url platform/app/2000-01-01-procfile %}). This limit can be increased via our support team. @@ -233,3 +251,6 @@ To learn more about events and notifiers, please visit the page dedicated to [routing-requests]: {% post_url platform/networking/public/2000-01-01-routing %}#requests-distribution [Scalingo Autoscaler]: {% post_url platform/app/scaling/2000-01-01-scalingo-autoscaler %} +[choosing-container-size]: {% post_url platform/app/scaling/2000-01-01-choosing-container-size %} +[metrics]: {% post_url platform/app/2000-01-01-metrics %} +[optimizing-architecture]: {% post_url platform/app/scaling/2000-01-01-optimizing-application-architecture %} diff --git a/src/_posts/platform/app/scaling/2000-01-01-scalingo-autoscaler.md b/src/_posts/platform/app/scaling/2000-01-01-scalingo-autoscaler.md index 5460348c6..7274cd9d2 100644 --- a/src/_posts/platform/app/scaling/2000-01-01-scalingo-autoscaler.md +++ b/src/_posts/platform/app/scaling/2000-01-01-scalingo-autoscaler.md @@ -1,7 +1,7 @@ --- title: Scalingo Autoscaler nav: Scalingo Autoscaler -modified_at: 2025-12-29 11:04:00 +modified_at: 2026-05-12 00:00:00 tags: app scaling autoscaling metrics autoscaler index: 20 --- @@ -21,7 +21,7 @@ metric while remaining within strict boundaries to prevent unforeseen costs. An Autoscaler is linked to a [process type]({% post_url platform/app/2000-01-01-procfile %}), which means you can have multiple Autoscalers for the same application, as long -as each one is setup for a different process type. Each Autoscaler can be setup +as each one is set up for a different process type. Each Autoscaler can be set up differently. When the configured metric deviates from the defined *target*, the Autoscaler @@ -44,22 +44,22 @@ to take action: round, ensuring a progressive and controlled adjustment. When the metric is RPM per container, the Autoscaler is able to add more than one container per decision round when required, allowing to scale much faster. The maximum - number of containers limit is still honoured in such a case. + number of containers still applies in such a case. These rules are designed to prevent the application from scaling wildly. They make autoscaling effective at handling moderately increasing or decreasing metrics, but less effective at managing sudden, massive spikes. For such cases, -and considering they are predictable, we usually adivse to manually scale the +and considering they are predictable, we usually advise to manually scale the application to an appropriate container formation. -## Chosing a Metric +## Choosing a Metric An Autoscaler can depend on 6 different metrics: | Metric | Kind | Keyword | | ------------------------------------------------------------------------ | ----------- | ------------------- | -| [Requests Per Minute (RPM) per container](rpm-per-container-recommended) | `router` | `rpm_per_container` | +| [Requests Per Minute (RPM) per container](#rpm-per-container-recommended) | `router` | `rpm_per_container` | | [Response Time](#response-time) | `router` | `p95_response_time` | | [Number of 5xx errors](#5xx-errors) | `router` | `5XX` | | [CPU consumption](#cpu-consumption) | `technical` | `cpu` | @@ -147,7 +147,7 @@ distribute the load. However, if high CPU usage persists despite autoscaling, it may indicate that your application requires more powerful containers to run properly. In such -cases, switching for a larger plan (vertical scaling) can provide more CPU +cases, switching to a larger plan (vertical scaling) can provide more CPU priority per container, thus enhancing the ability of your application to deal with resource-intensive scenarios. @@ -235,7 +235,7 @@ resource-intensive endpoints of your application. Although the Scalingo Autoscaler itself is free, the additional containers started during a scale-out operation are billed like any other container (on -the other hand, scaling-in allows to save costs). +the other hand, scaling-in can save costs). Consequently, billing depends on the type of container you chose for your application (M is the default container size), on the maximum number of @@ -247,7 +247,7 @@ workload. {% warning %} Adding an Autoscaler also immediately enables it! -Since this can lead to additional costs, please make sure to chose appropriate +Since this can lead to additional costs, please make sure to choose appropriate options and values before validating. [It can be disabled](#disabling-an-autoscaler) if needed. {% endwarning %} @@ -258,7 +258,7 @@ options and values before validating. 2. Click on the **Resources** tab 3. Locate the **Containers** block 4. In this block, locate the **Scale** button next to the process type for - which you want to setup the Autoscaler + which you want to set up the Autoscaler 5. Click the down arrow next to the **Scale** button 6. From the dropdown menu, select **Setup autoscaler** 7. The following popup window appears: @@ -269,15 +269,15 @@ options and values before validating. 1. Pick the minimum number of containers for this process type (minimum is 2) 2. Pick the maximum number of containers for this process type - 3. Chose the metric to watch - 4. Chose a value above which the Autoscaler considers scaling-out + 3. Choose the metric to watch + 4. Choose a value above which the Autoscaler considers scaling-out 5. Validate by clicking the **Confirm** button 9. **The Autoscaler is configured and enabled** ### Using the Command Line -1. Make sure you have correctly [setup the Scalingo command line tool]({% post_url tools/cli/2000-01-01-start %}) -2. From the command line, run the following command to setup the Autoscaler: +1. Make sure you have correctly [set up the Scalingo command line tool]({% post_url tools/cli/2000-01-01-start %}) +2. From the command line, run the following command to set up the Autoscaler: ```bash scalingo --app my-app autoscalers-add --container-type \ --metric --target \ @@ -288,10 +288,10 @@ options and values before validating. Name of the process type to scale (e.g. `web`, `clock`, `scheduler`, ...) - `metric`\ Name of the metric to watch.\ - Please refer to the *Keyword* column of the [metrics table](#available-metrics) + Please refer to the *Keyword* column of the [metrics table](#choosing-a-metric) for available values. - `target`\ - The value for metric that serves as boundary to trigger a scale operation + The metric value that serves as a boundary to trigger a scale operation - `min`\ Minimum number of containers to run - `max`\ @@ -321,13 +321,13 @@ options and values before validating. `web` process type when the total number of requests received by the application divided by the number of running `web` containers exceeds 1000. It will start a maximum of 10 containers.\ - Please refer to the *Keyword* column of the [metrics table](#available-metrics) + Please refer to the *Keyword* column of the [metrics table](#choosing-a-metric) for available values. ## Enabling the Autoscaler -Enabling (or re-enabling) an Autoscaler allows to put a previously [disabled](#disabling-an-autoscaler) +Enabling (or re-enabling) an Autoscaler allows you to put a previously [disabled](#disabling-an-autoscaler) Autoscaler back in action, using the saved configuration. When enabling an Autoscaler, and depending on the current state, the platform @@ -346,8 +346,8 @@ may decide to either scale-out (i.e. boot up additional containers) or scale-in ### Using the Command Line -1. Make sure you have correctly [setup the Scalingo command line tool]({% post_url tools/cli/2000-01-01-start %}) -2. Make sure you have [added and configured an Autoscaler](#configuring-an-autoscaler) +1. Make sure you have correctly [set up the Scalingo command line tool]({% post_url tools/cli/2000-01-01-start %}) +2. Make sure you have [added and configured an Autoscaler](#creating-an-autoscaler) 3. From the command line, enable the Autoscaler: ```bash scalingo --app my-app autoscalers-enable @@ -373,14 +373,14 @@ may decide to either scale-out (i.e. boot up additional containers) or scale-in ## Disabling an Autoscaler -Disabling an Autoscaler allows to put it out of action, while saving its -configuration for later use. It can be [re-enabled](#enabling-an-autoscaler) +Disabling an Autoscaler allows you to put it out of action, while saving its +configuration for later use. It can be [re-enabled](#enabling-the-autoscaler) anytime. Sometimes it can be useful to temporarily disable an Autoscaler to only rely on manual scaling, be it for testing purposes, to handle a planned peak such as the Christmas period for an e-commerce website, and so on... This feature -allows to put an Autoscaler aside for an undetermined amount of time, after +allows you to put an Autoscaler aside for an undetermined amount of time, after which it can be re-enabled with the same configuration. When disabling an Autoscaler, the platform does not scale-in. The number of @@ -402,8 +402,8 @@ running containers remains the same. ### Using the Command Line -1. Make sure you have correctly [setup the Scalingo command line tool]({% post_url tools/cli/2000-01-01-start %}) -2. Make sure you have [added and configured an Autoscaler](#configuring-an-autoscaler) +1. Make sure you have correctly [set up the Scalingo command line tool]({% post_url tools/cli/2000-01-01-start %}) +2. Make sure you have [added and configured an Autoscaler](#creating-an-autoscaler) 3. From the command line, disable the Autoscaler: ```bash scalingo --app my-app autoscalers-disable @@ -429,7 +429,7 @@ running containers remains the same. ## Monitoring the Autoscaler -The following event is available to monitor the Autoscaler executions: +The following event is available to monitor Autoscaler executions: | Event | Description | | ------------ | -------------------------------------------------------------------- | diff --git a/src/_posts/platform/app/troubleshooting/2000-01-01-runtime-issues.md b/src/_posts/platform/app/troubleshooting/2000-01-01-runtime-issues.md index 031820d95..d33059bbb 100644 --- a/src/_posts/platform/app/troubleshooting/2000-01-01-runtime-issues.md +++ b/src/_posts/platform/app/troubleshooting/2000-01-01-runtime-issues.md @@ -46,8 +46,8 @@ error and the impact it has on your application: The very first step to mitigate the consequences of a Runtime Error is to ensure that you have regular, tested backups (for databases, this feature is -included in all our *business* plans) and to setup some -[redundancy]({% post_url platform/app/scaling/2000-01-01-scaling %}#redundancy). +included in all our *business* plans) and to set up some +[redundancy]({% post_url platform/app/scaling/2000-01-01-scaling %}#horizontal-scaling). Additionally, we generally advise to have a disaster recovery plan in place. This plan should ideally outline the actions to be taken in the event of such a