diff --git a/src/_posts/languages/go/2000-01-01-start.md b/src/_posts/languages/go/2000-01-01-start.md index ffebaec9c..59b6b628c 100644 --- a/src/_posts/languages/go/2000-01-01-start.md +++ b/src/_posts/languages/go/2000-01-01-start.md @@ -68,6 +68,22 @@ Because the buildpack installs compiled executables to `bin`, the `go-post-compile` hook can be written in Go if it's installed by the specified [``]({% post_url languages/go/2000-01-01-gomod %}). +## Memory Management + +Go applications can use `GOMEMLIMIT` to define a soft memory limit for the Go +runtime. In a Scalingo container, set it explicitly when you need tighter memory +control: + +```bash +$ scalingo --app my-app env-set GOMEMLIMIT=400MiB +``` + +Choose a value lower than `CONTAINER_MEMORY`, because `GOMEMLIMIT` is not a hard +limit for the full process memory. For more details, refer to the +[Go runtime environment variables][go-runtime-env]. + ## Buildpack More information at [https://github.com/Scalingo/go-buildpack](https://github.com/Scalingo/go-buildpack). + +[go-runtime-env]: https://pkg.go.dev/runtime#hdr-Environment_Variables diff --git a/src/_posts/languages/java/2000-01-01-start.md b/src/_posts/languages/java/2000-01-01-start.md index 6655a4e89..c0f3ed7bb 100644 --- a/src/_posts/languages/java/2000-01-01-start.md +++ b/src/_posts/languages/java/2000-01-01-start.md @@ -1,7 +1,7 @@ --- title: Java on Scalingo nav: Introduction -modified_at: 2026-04-23 12:00:00 +modified_at: 2026-05-11 12:00:00 tags: java index: 1 --- @@ -114,13 +114,26 @@ faster dependency resolution. However neither the `mvn` executable nor the By default the `-Xmx` configuration of the JVM depends on the size of container you selected for your application: -| Container Size | Maximum Heap Size (MB) | -| -------------: | ------------------------------------: | -| S | `160` | -| M | `300` | -| L | `671` | -| XL | `1536` | -| 2XL and above | ~80% of the RAM allocated in the plan | +| Container Size | Memory (MB) | Maximum Heap Size (MB) | +| :------------: | ----------: | ---------------------: | +| S | 256 | 160 | +| M | 512 | 300 | +| L | 1024 | 671 | +| XL | 2048 | 1536 | +| 2XL | 4096 | 3176 | + +This setting controls the Java heap, not every memory allocation made by the JVM +process. + +If your application needs an explicit heap limit, define it with +`JAVA_TOOL_OPTIONS`: + +```bash +$ scalingo --app my-app env-set JAVA_TOOL_OPTIONS="-Xmx512m" +``` + +For more information about JVM memory options, refer to the +[Java command documentation][java-command]. ### Choose a Maven Version @@ -159,8 +172,8 @@ $ scalingo env-set MAVEN_CUSTOM_GOALS="clean package" $ scalingo env-set MAVEN_CUSTOM_OPTS="--update-snapshots -DskipTests=true" ``` -Other options are available for [defining custom a `settings.xml` -file](https://devcenter.heroku.com/articles/using-a-custom-maven-settings-xml). +Other options are available for [defining a custom `settings.xml` +file](https://maven.apache.org/settings.html). ### Installation of JDK only (no Maven) @@ -196,3 +209,5 @@ account. More information at [https://github.com/Scalingo/java-buildpack](https://github.com/Scalingo/java-buildpack). + +[java-command]: https://docs.oracle.com/en/java/javase/25/docs/specs/man/java.html diff --git a/src/_posts/languages/nodejs/2000-01-01-start.md b/src/_posts/languages/nodejs/2000-01-01-start.md index 3aa5f52f9..eb000c3f7 100644 --- a/src/_posts/languages/nodejs/2000-01-01-start.md +++ b/src/_posts/languages/nodejs/2000-01-01-start.md @@ -1,7 +1,7 @@ --- title: Node.js nav: Introduction -modified_at: 2026-05-07 12:00:00 +modified_at: 2026-05-18 00:00:00 tags: nodejs index: 1 --- @@ -216,6 +216,32 @@ Example of `package.json`: } ``` +## Memory Management + +On Scalingo, the Node.js buildpack automatically defines `WEB_CONCURRENCY` +when it is not already set. The value is calculated from the memory available +in the container and the `WEB_MEMORY` value: + +```text +WEB_CONCURRENCY = MEMORY_AVAILABLE / WEB_MEMORY +``` + +By default, `WEB_MEMORY` is set to `512` MB. + +You can override `WEB_CONCURRENCY` or `WEB_MEMORY` if the default values do not +fit your application workload. + +If your application needs an explicit V8 old-space limit, use `NODE_OPTIONS`: + +```bash +$ scalingo --app my-app env-set NODE_OPTIONS="--max-old-space-size=512" +``` + +The value is expressed in megabytes. This setting can help make memory usage +more predictable, but increasing it does not fix memory leaks. + +For more details, refer to the [official Node.js memory guide][nodejs-memory-guide]. + ### Node.js Build Hooks If your application has a build step that you would like to run when you @@ -438,3 +464,5 @@ The solution is to change the content of the Procfile to directly start the Node ```yaml web: node server.js ``` + +[nodejs-memory-guide]: https://nodejs.org/learn/diagnostics/memory/understanding-and-tuning-memory diff --git a/src/_posts/languages/php/2000-01-01-start.md b/src/_posts/languages/php/2000-01-01-start.md index e090469ba..a87bb1a95 100644 --- a/src/_posts/languages/php/2000-01-01-start.md +++ b/src/_posts/languages/php/2000-01-01-start.md @@ -1,7 +1,7 @@ --- title: PHP on Scalingo nav: Introduction -modified_at: 2026-05-06 12:00:00 +modified_at: 2026-05-11 12:00:00 tags: php index: 1 --- @@ -114,7 +114,6 @@ The default values for `pm.max_children` are based on the `memory_limit` parameter of the [PHP configuration](https://github.com/Scalingo/php-buildpack/blob/master/conf/php/php.ini#L15), the used formula is: `floor(available_memory / php_memory_limit) + 2` -{: .table } | Container Size | Memory (MB) | Default Concurrency | | -------------: | ----------: | ------------------: | | S | 256 | 3 | @@ -126,11 +125,11 @@ the used formula is: `floor(available_memory / php_memory_limit) + 2` ### Concurrency Fine Tuning Fine tuning the value of the `WEB_CONCURRENCY` environment variable is a bit -tricky and must be handled with care. There is no magic formulae and one must -load test his application to find the best value matching his use case. If the +tricky and must be handled with care. There is no magic formula and you should +load test your application to find the best value matching your use case. If the application is swapping, you might need to lower the value of `WEB_CONCURRENCY` and increase the amount of containers. On the contrary, if your application -does not use all his memory, one can try to slightly increase the +does not use all its memory, you can try to slightly increase the `WEB_CONCURRENCY` value and make sure the application does not start swapping. Note that if the `WEB_CONCURRENCY` value is too high your application will not diff --git a/src/_posts/platform/app/2000-01-01-metrics.md b/src/_posts/platform/app/2000-01-01-metrics.md index 882b91079..e629afdca 100644 --- a/src/_posts/platform/app/2000-01-01-metrics.md +++ b/src/_posts/platform/app/2000-01-01-metrics.md @@ -1,7 +1,7 @@ --- title: Application Metrics nav: Metrics -modified_at: 2026-01-02 12:00:00 +modified_at: 2026-05-05 00:00:00 tags: app metrics index: 35 --- @@ -23,17 +23,20 @@ The application chart displays global data that are not container specific: events and routing metrics. The **Requests per minute** chart show the number of requests the application -receives per minute, the famous **RPM**. The number of server error responses generated by the application (HTTP responses in the 500 range) is displayed on the same chart as red bars. +receives per minute, the famous **RPM**. The number of server error responses +generated by the application (HTTP responses in the 500 range) is displayed on +the same chart as red bars. **Note**: 504 and 503 errors can be generated by our reverse proxy. More information is available in the [routing documentation][routing-errors]. On top of this chart, all the events that happened during the -viewing period are displayed. This can help you link the application behaviour with events -that happened on the platform, e.g. spot a deployment that contains a memory -leak or follow your application behaviour after a scale operation. +viewing period are displayed. This can help you link the application behaviour +with events that happened on the platform, e.g. spot a deployment that contains +a memory leak or follow your application behaviour after a scale operation. -A lot of events are available on the application timeline but only a few relevant are displayed on the metrics view: +A lot of events are available on the application timeline but only a few +relevant are displayed on the metrics view: - Restart event - Deploy event @@ -61,10 +64,11 @@ The container charts use the container types defined in your [Procfile]({% post_url platform/app/2000-01-01-procfile %}). For each container type, two charts are shown. The first one shows the **CPU -usage** and the second one the **memory** and **swap** usage of this type of -container. +usage** and the second one the **memory usage** and **swap usage** usage of this +type of container. -The CPU chart may exceed 100% if the application uses more than one core of the CPU. +The CPU chart may exceed 100% if the application uses more than one core of the +CPU. For the memory chart, the memory (in blue) and swap usage (in red) are stacked. That way the total memory usage of the application can be @@ -84,45 +88,16 @@ The swap usage can increase in two different situations: {% note %} Protip: Is your application slow? Check your swap usage! If your app swaps a lot it will significantly alter your application performance. You'd -better reduce its memory usage or use a bigger container size. +better reduce its memory usage or use a bigger +[container size][container-sizes]. {% endnote %} **Note**: The swap line is only shown if the swap usage exceeds 2% of the -[container memory limit]({% post_url -platform/internals/2000-01-01-container-sizes %}). +[container memory limit][container-sizes]. If the application has more than one container of a specific type, these charts show the mean CPU usage / memory consumption of all containers of the same type. -## Behavior when memory and swap are fully consumed - -When an application consumes all its allocated memory (RAM + swap), the system applies a protection mechanism called the **OOM Killer** (Out of Memory Killer). - -### Sequence of events - -1. The application progressively uses all available RAM -2. The system starts using swap space (visible in red on the memory chart) -3. When memory and swap reach 100% usage, the OOM Killer intervenes -4. The application is immediately terminated by the system - -### Observable consequences - -* **Abrupt termination:** The application stops without a graceful shutdown process -* **Automatic restart:** The container restarts according its configuration -* **Restart event:** A "Restart" event appears in the metrics timeline -* **Data loss:** All non-persisted data in memory is lost - -### Prevention and monitoring - -To avoid this scenario: - -* Regularly monitor memory charts in the Metrics tab -* Set up alerts before reaching memory limits -* Analyse usage spikes in correlation with deployment events -* Consider upgrading to a larger [container size](/platform/internals/container-sizes) if needed - -**Note:** The OOM Killer is a system protection mechanism. If your application regularly experiences OOM events, it typically indicates a need for code optimization or increased allocated resources. - ## Detailed View If the application has more than one container of a type defined in its @@ -134,3 +109,4 @@ debugging process. [notifiers]: {% post_url platform/app/2000-01-01-notifiers %} [routing-errors]: {% post_url platform/networking/public/2000-01-01-routing %}#http-errors +[container-sizes]: {% post_url platform/internals/2000-01-01-container-sizes %} 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..5ea77ee7c 100644 --- a/src/_posts/platform/app/scaling/2000-01-01-scaling.md +++ b/src/_posts/platform/app/scaling/2000-01-01-scaling.md @@ -74,9 +74,9 @@ Here is a quick comparison table, in the context of a Platform as a Service: ## Limitations - 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 - [dedicated documentation page]({% post_url platform/internals/2000-01-01-container-sizes %}). + currently boot is the `2XL` container, with 4GB of RAM. See the + [container sizes][container-sizes] documentation for the full list of sizes + and their specifications. - Horizontal scaling is limited by default to a maximum of 10 containers per [process type]({% post_url platform/app/2000-01-01-procfile %}). This limit can be increased via our support team. @@ -233,3 +233,4 @@ 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 %} +[container-sizes]: {% post_url platform/internals/2000-01-01-container-sizes %} 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..66d06a694 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 @@ -238,9 +238,9 @@ started during a scale-out operation are billed like any other container (on the other hand, scaling-in allows to 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 -containers set in the Autoscaler configuration and on your application -workload. +application (M is the default +[container size][container-sizes]), on the maximum number of containers set in +the Autoscaler configuration and on your application workload. ## Creating an Autoscaler @@ -439,3 +439,4 @@ To learn more about events and notifiers, please visit the page dedicated to [app notifiers]({% post_url platform/app/2000-01-01-notifiers %}). [scaling-v]: {% post_url platform/app/scaling/2000-01-01-scaling %}#vertical-scaling +[container-sizes]: {% post_url platform/internals/2000-01-01-container-sizes %} diff --git a/src/_posts/platform/app/task-scheduling/2000-01-01-scalingo-scheduler.md b/src/_posts/platform/app/task-scheduling/2000-01-01-scalingo-scheduler.md index c02de6d08..63f3f9ce9 100644 --- a/src/_posts/platform/app/task-scheduling/2000-01-01-scalingo-scheduler.md +++ b/src/_posts/platform/app/task-scheduling/2000-01-01-scalingo-scheduler.md @@ -76,7 +76,8 @@ the commands are run are billed like any other [one-off container]({% post_url platform/app/2000-01-01-tasks %}). Consequently, billing depends on the type of container you defined in your task -(M is the default container size) and on the job lifespan. +(M is the default +[container size][container-sizes]) and on the job lifespan. For example, if your job runs during 5 minutes, you will be billed 5 minutes of an M container. @@ -187,3 +188,5 @@ remove the file. Logs for scheduled tasks are included in the [application logs]({% post_url platform/app/2000-01-01-logs %}), next to other containers logs. + +[container-sizes]: {% post_url platform/internals/2000-01-01-container-sizes %} 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..83ac38abe 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 @@ -1,7 +1,7 @@ --- title: Runtime Issues -modified_at: 2026-05-04 00:00:00 -tags: app runtime crash recovery troubleshooting +modified_at: 2026-05-11 00:00:00 +tags: app runtime crash recovery troubleshooting oom memory index: 3 --- @@ -25,7 +25,8 @@ The most common causes are: - Configuration issues - Bugs in your application code - Uncaught exception in your code (especially with non-compiled languages) -- Insufficient resources +- Insufficient resources, such as an Out of Memory (OOM) crash when the + application consumes all its available memory - Temporary error/unavailability of an external resource A Runtime Error can have several consequences, depending on the severity of the @@ -112,5 +113,41 @@ when a Timeout Error occurs). You can modify this behavior by tweaking your [Notifier's configuration]({% post_url platform/app/2000-01-01-notifiers %}). -The `app_crashed`, `app_crashed_repeated` and the `app_deploy` events can be +The `app_crashed`, `app_crashed_repeated` and the `app_deployed` events can be particularly worth considering. + +## Common Runtime Error Patterns + +### Out of Memory Crashes + +When an application consumes all its allocated memory (RAM + swap), the system +applies a protection mechanism called the **OOM Killer** (Out of Memory Killer). + +The usual sequence is: + +1. The application progressively uses all available RAM. +2. The system starts using swap space. +3. When memory and swap reach 100% usage, the OOM Killer intervenes. +4. The application is immediately terminated by the system. + +This can have several observable consequences: + +- Abrupt termination: the application stops without a graceful shutdown process. +- Automatic restart: the container is restarted following our [runtime error recovery process](#recovering-from-a-runtime-error). +- Restart event: a "Restart" event appears in the metrics timeline. +- Data loss: all non-persisted data in memory is lost. + +To reduce the risk of OOM crashes: + +- Regularly monitor memory charts in the [Metrics tab][metrics]. +- Set up [alerts][alerts] before reaching memory limits. +- Analyze usage spikes in correlation with deployment events. +- Consider upgrading to a larger [container size][container-sizes] if needed. + +The OOM Killer is a system protection mechanism. If your application regularly +experiences OOM events, it typically indicates a need for code optimization or +increased allocated resources. + +[alerts]: {% post_url platform/app/2000-01-01-alerts %} +[container-sizes]: {% post_url platform/internals/2000-01-01-container-sizes %} +[metrics]: {% post_url platform/app/2000-01-01-metrics %} diff --git a/src/_posts/platform/internals/2000-01-01-container-sizes.md b/src/_posts/platform/internals/2000-01-01-container-sizes.md index f92bbd290..3864caa87 100644 --- a/src/_posts/platform/internals/2000-01-01-container-sizes.md +++ b/src/_posts/platform/internals/2000-01-01-container-sizes.md @@ -1,83 +1,46 @@ --- title: Container Sizes -modified_at: 2015-12-02 00:00:00 -tags: internals containers sizes +modified_at: 2026-05-05 00:00:00 +tags: containers sizes index: 2 --- -## Comparative Table +The following table provides a side-by-side comparison of resources and process +limits applied to each container size, allowing for a clear overview of the +capabilities and isolation characteristics associated with each profile. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameMemoryCPU PriorityPID LimitPrice
S - Small256MBLow1280.01€/h
M - Medium (Default)512MBStandard2560.02€/h
L - Large1GBStandard5120.04€/h
XL - eXtra Large2GBHigh10240.08€/h
2XL - eXtra eXtra Large4GBHigh20480.16€/h
-
+| Size | Memory (MB) | Swap (MB) | [CPU Priority](#cpu) | [PID](#pid) | [FD](#fd) | +| :-----: | ----------: | --------: | :------------------: | ----------: | :-------: | +| **S** | 256 | 512 | Low | 128 | 1048576 | +| **M** | 512 | 1024 | Standard | 256 | 1048576 | +| **L** | 1024 | 2048 | Standard | 512 | 1048576 | +| **XL** | 2048 | 4096 | High | 1024 | 1048576 | +| **2XL** | 4096 | 8192 | High | 2048 | 1048576 | -Bigger container sizes are available upon request on the support. -As a note, each new process requires a PID. And inside each process, each thread needs one too. +The default container size is **M**. -## Availability of the Sizes +Prices are available on the [Scalingo pricing page](https://scalingo.com/pricing). -Our 30 days free trial only gives you access to small and medium containers, if you want -to use another kind of size, please [fill your billing profile and payment -method](https://dashboard.scalingo.com/billing). -## Container Limits +{: #cpu}**CPU Priority** +: All containers can use all available CPU cores. -Containers have various limits depending on their size. Here is a comprehensive list: + - A *High* priority container receives twice the CPU share of a *Standard* + priority container when CPU resources are contested. + - Following the same logic, a *Low* priority container receives half the CPU + share of a *Standard* priority container when CPU resources are contested. -- RAM: cf. above-mentioned table -- Swap: twice the amount of RAM. -- CPU access: all containers have access to all CPU cores. But higher priority - means twice as much priority compared to standard priority. For example, - consider three containers, one has a high priority and two others have a - standard priority. When processes in all three containers attempt to use - 100% of CPU, the first container would receive 50% of the total CPU time and - the two others would receive 25%. -- PID limits: from 128 (S) to 2048 (2XL). -- Ulimit nofile: 1048576. Maximum number of files an application can open. + For example, if three containers are fully utilizing the CPU — one with High + priority and two with Standard priority — the High priority container would + receive 50% of the total CPU time, while each Standard priority container + would receive 25%. + +{: #pid}**PID** +: Maximum number of processes the container can spawn. + +{: #fd}**FD** (`nofile`) +: Maximum number of file descriptors a process can open. + + +*[PID]: Process IDentifier +*[FD]: File Descriptors