Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
00a42d3
fix(docs): correct event name from `app_deploy` to `app_deployed`
benjaminach May 5, 2026
7280e1a
Table is converted to markdown and various changes
benjaminach May 5, 2026
650382a
Update the page position
benjaminach May 5, 2026
a705463
Precisions about OOM Crash
benjaminach May 5, 2026
4211433
add Application Resources documentation and move the OOM section from…
benjaminach May 5, 2026
a8f73bb
docs(app): move OOM guidance to runtime issues
benjaminach May 11, 2026
08a1e4f
Restore initial position
benjaminach May 11, 2026
ad8d2fb
docs(runtime): move OOM details to error patterns
benjaminach May 11, 2026
549065b
docs: clarify container memory references
benjaminach May 11, 2026
18a94ce
docs(languages): add memory management pointers
benjaminach May 11, 2026
3c990a1
Merge branch 'master' into feat/oom-crash
benjaminach May 11, 2026
5ba6929
Apply suggestions from code review
benjaminach May 12, 2026
a2e3cc1
Remove PHP "Memory Management" section since it’s a duplicate of an e…
benjaminach May 12, 2026
7f43c3c
Revert changes to the Python file because the web_concurrency section…
benjaminach May 12, 2026
a3c23af
Revert changes to the Ruby file because the web_concurrency section a…
benjaminach May 12, 2026
db07854
Apply suggestions from code review
benjaminach May 18, 2026
3e167b0
docs(java): merge JVM memory guidance
benjaminach May 18, 2026
ee17f0f
fix(nodejs): clarify WEB_CONCURRENCY memory calculation
benjaminach May 18, 2026
5959495
chore: update 'Container Sizes' page
Frzk May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/_posts/languages/go/2000-01-01-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
[`<packagespec>`]({% 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
38 changes: 28 additions & 10 deletions src/_posts/languages/java/2000-01-01-start.md
Original file line number Diff line number Diff line change
@@ -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
---
Expand Down Expand Up @@ -114,13 +114,29 @@ 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 and above | 4096 and above | ~80% of the RAM allocated in the plan |

Comment thread
benjaminach marked this conversation as resolved.
Outdated
### Memory Management
Comment thread
benjaminach marked this conversation as resolved.
Outdated

Scalingo sets the default JVM heap size according to the selected container
size. 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

Expand Down Expand Up @@ -159,8 +175,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).
Comment thread
benjaminach marked this conversation as resolved.

### Installation of JDK only (no Maven)

Expand Down Expand Up @@ -196,3 +212,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
23 changes: 22 additions & 1 deletion src/_posts/languages/nodejs/2000-01-01-start.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Node.js
nav: Introduction
modified_at: 2026-05-07 12:00:00
modified_at: 2026-05-11 12:00:00
tags: nodejs
index: 1
---
Expand Down Expand Up @@ -216,6 +216,24 @@ Example of `package.json`:
}
```

## Memory Management

Modern Node.js versions are container-aware and usually do not require setting
`--max-old-space-size` by default. For Node.js 20 and later, the default V8 heap
size is commonly around 50% of the container memory up to 4 GiB, then levels out
around 2 GiB, as documented for [Node.js 20 in containers][nodejs-container-memory].
Comment thread
benjaminach marked this conversation as resolved.
Outdated

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
Expand Down Expand Up @@ -438,3 +456,6 @@ 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
[nodejs-container-memory]: https://developers.redhat.com/articles/2025/10/10/nodejs-20-memory-management-containers
9 changes: 4 additions & 5 deletions src/_posts/languages/php/2000-01-01-start.md
Original file line number Diff line number Diff line change
@@ -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
---
Expand Down Expand Up @@ -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 |
Expand All @@ -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
Expand Down
58 changes: 17 additions & 41 deletions src/_posts/platform/app/2000-01-01-metrics.md
Original file line number Diff line number Diff line change
@@ -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
---
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Comment thread
benjaminach marked this conversation as resolved.

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
Expand All @@ -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 %}
7 changes: 4 additions & 3 deletions src/_posts/platform/app/scaling/2000-01-01-scaling.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Comment thread
Frzk marked this conversation as resolved.
- 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.
Expand Down Expand Up @@ -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 %}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 %}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 %}
Original file line number Diff line number Diff line change
@@ -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
---

Expand All @@ -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
Expand Down Expand Up @@ -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
Comment thread
benjaminach marked this conversation as resolved.
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 %}
Loading