DEV Community

Atsushi Suzuki
Atsushi Suzuki

Posted on

Troubleshooting the "JavaScript heap out of memory" Error in a Node.js Application on ECS

While running a Node.js application on ECS, it suddenly crashed with the error message "JavaScript heap out of memory." This article summarizes the cause of the issue and how I resolved it.

Error

Here is the log that was output at the time of the crash:

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
Enter fullscreen mode Exit fullscreen mode

This error occurs when Node.js exceeds the maximum memory allocation for the JavaScript heap. The default heap size for Node.js is approximately 1.4 GB on 64-bit systems. If your application requires more memory than this default limit, it will crash.

Cause

1. Default Heap Size of Node.js

The default heap size in Node.js is approximately 1.4 GB. Applications requiring more memory—such as those handling large-scale data processing—are prone to crashing due to this limitation. In my case, the application exceeded this limit due to a heavy data workload.

2. ECS Task Definition Resource Configuration

ECS imposes memory constraints on tasks using two parameters:

  • memory (hard limit): The maximum memory the task can use. If exceeded, the task is killed.
  • memoryReservation (soft limit): The memory that ECS attempts to reserve for the task. Tasks can exceed this limit if resources are available, but exceeding the memory value will still result in the task being killed.

Here were the initial settings for the task:

"memory": 2048,
"memoryReservation": 2048
Enter fullscreen mode Exit fullscreen mode

This configuration did not allocate enough memory for the Node.js process, which needs to account for both the heap (1.4 GB) and additional memory for buffers, native modules, and other system operations. As a result, the task crashed due to insufficient memory.

Solution

1. Expanding the Heap Size

The --max-old-space-size option in Node.js allows you to increase the heap size. For example, the following command sets the heap size to 2 GB:

node --max-old-space-size=2048 dist/main.js
Enter fullscreen mode Exit fullscreen mode

In ECS, you can apply this setting either by modifying the Dockerfile or by adding a command section to the task definition.

Task Definition Example

The command section in the task definition can override the default Node.js startup command and include the --max-old-space-size option:

"command": [
  "node",
  "--max-old-space-size=2048",
  "dist/main"
]
Enter fullscreen mode Exit fullscreen mode

2. Increasing ECS Task Memory Allocation

The Node.js process consumes memory for more than just the heap. Additional memory is used for:

  • Native modules and compiled code
  • Buffers (e.g., for file I/O and network operations)

To prevent crashes, I increased the memory and memoryReservation settings in the ECS task definition to values that comfortably exceed the heap size:

"memoryReservation": 3072,
"memory": 4096
Enter fullscreen mode Exit fullscreen mode

Implementation Examples

Dockerfile Adjustment

If you want to apply the heap size setting directly in the Dockerfile, you can modify the CMD as follows:

CMD ["node", "--max-old-space-size=2048", "dist/main"]
Enter fullscreen mode Exit fullscreen mode

Task Definition Adjustment

However, modifying the task definition instead of the Dockerfile allows for greater flexibility across different environments. This approach avoids hardcoding settings into the image and simplifies adjustments for staging and production environments.

Here’s the updated task definition:

{
  "containerDefinitions": [
    {
      "name": "app",
      "memory": 3072,
      "memoryReservation": 3072,
      "command": [
        "node",
        "--max-old-space-size=2048",
        "dist/main"
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/app",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ],
  "cpu": "1024",
  "memory": "3072"
}
Enter fullscreen mode Exit fullscreen mode

Why Use the Task Definition for Configuration?

If the heap size is configured in the Dockerfile, it will apply to all environments (e.g., development, staging, production). This lack of flexibility could be problematic if different environments require different heap sizes. By using the task definition, you can adjust the settings per environment without rebuilding the Docker image.

Conclusion

The "JavaScript heap out of memory" error can be addressed by:

  1. Increasing the heap size using --max-old-space-size.
  2. Allocating sufficient memory to the ECS task to accommodate both the heap and additional memory usage.

This solution ensures stable operation without unexpected crashes. If you encounter similar issues, consider monitoring your application’s memory usage with AWS CloudWatch Logs and revising your configurations as needed.

Top comments (0)