Part of Hosting by frameworkHosting · Troubleshooting

“JavaScript heap out of memory” during a build, and out-of-memory kills after it.

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory means Node hit its own heap limit, not that the machine ran out of RAM. Raise the limit with NODE_OPTIONS=--max-old-space-size only if the container really has that memory. Otherwise make the build use less, or give it more memory.

Facts checked

Two failures that look alike

A build can run out of memory in two places, and the fixes point in opposite directions. Check which one you have before changing anything.

# The shape of a heap-limit failure (trimmed)
<--- Last few GCs --->
... Mark-Compact ... MB ...

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
 1: ... node::Abort() ...
 ...
# the process then exits with code 134
What you seeExit codeWho stopped itWhat helps
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory (or Ineffective mark-compacts near heap limit), with a stack trace † † †134 (128 + SIGABRT)V8, at its heap limit. The container may still have free memoryA higher --max-old-space-size, if the container has room; or a smaller build
No error from Node. The log stops, maybe with Killed † †137 (128 + SIGKILL)The kernel, because the container passed its memory limitMore memory for the container, or a smaller build. A higher heap limit makes it worse

† Competitor details come from each vendor’s own published pages on the dates shown; prices and plans change, so check the vendor before you decide. `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory` (or `Ineffective mark-compacts near heap limit`), with a stack trace (2026-10-29) · `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory` (or `Ineffective mark-compacts near heap limit`), with a stack trace (2026-10-29) · `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory` (or `Ineffective mark-compacts near heap limit`), with a stack trace (2026-10-29) · No error from Node. The log stops, maybe with `Killed` (2026-10-29) · No error from Node. The log stops, maybe with `Killed` (2026-10-29)

Setting --max-old-space-size without making it worse

The flag sets the size of V8’s old-generation heap, in MiB. Node accepts it in NODE_OPTIONS, so it reaches every Node process your build script starts:

  • Stay under the container’s memory. Node’s own docs suggest 1536 on a machine with 2 GiB, to leave room for everything outside the heap. Native modules, buffers and source maps held outside V8 all need memory too.
  • Set it too high and you trade exit 134 for exit 137. The heap grows past what the container allows and the kernel kills the build with no message at all.
  • Set it too low and you cause the error. A NODE_OPTIONS copied from an old README, such as --max-old-space-size=2048, caps a build that had 6 GB to use.
# One build, any shell that sets env vars this way (Linux, macOS)
NODE_OPTIONS=--max-old-space-size=3072 npm run build

# Check the limit Node is actually using, in MB
node -e "console.log(v8.getHeapStatistics().heap_size_limit / 1048576)"

Build memory on Canner

Each build runs in its own sandbox with a memory budget set by your plan. Canner passes --max-old-space-size to the build for you, sized to that budget minus 200 MB for memory outside the heap, so most projects should not set it at all. The plans and limits docs list the numbers; the pricing page has the plans side by side.

  • Find the peak. After each step the log prints a line like [canner] build used up to 3.4 GB of memory. Compare it with your budget before deciding what to change.
  • When the build is killed, the message is build ran out of memory and was killed. On large projects this is often the type-checking or bundling step, followed by the Next.js fix below.
  • When your own NODE_OPTIONS is the cause, Canner says so: “Your NODE_OPTIONS environment variable limits Node's heap to 2048 MB, well below the memory this build was given, so the build ran out of memory at that limit. Remove --max-old-space-size from NODE_OPTIONS (or raise it) and deploy again.” The automatic retry is skipped in that case, since more memory wouldn’t help.
  • A retried build says why. Its log starts with [canner] the last build ran out of memory, so this one runs with more: 6 GB instead of your plan's 4 GB (once a month).
Build memoryNotes
StarterUp to 4 GBFree plan
LiveUp to 6 GBApp RAM adds 1 GB of build memory for each GB assigned to the project
Automatic retry4 → 6 GB on Starter, 6 → 8 GB on LiveOnce a month per organization, for a production build from GitHub that ran out of memory. Not for previews, uploads or CLI deploys

Make the build need less

More memory hides the problem until the project grows again. For Next.js, these settings come from its own memory guide:

SettingWhat it savesTrade-off
typescript: { ignoreBuildErrors: true } in next.config, plus tsc --noEmit in CI †Type checking, often the largest peak in a big projectType errors are no longer caught by the build; run the check elsewhere before you merge
productionBrowserSourceMaps: false and experimental.serverSourceMaps: false †Source map generationHarder-to-read stack traces from production
experimental.webpackMemoryOptimizations: true (Next.js 15 and later) †Peak memory in webpackSlightly slower compiles
next build --experimental-debug-memory-usage †Nothing by itself; prints heap use through the build and takes heap snapshots near the limitFor diagnosis only

† Competitor details come from each vendor’s own published pages on the dates shown; prices and plans change, so check the vendor before you decide. `typescript: { ignoreBuildErrors: true }` in `next.config`, plus `tsc --noEmit` in CI (2026-10-29) · `productionBrowserSourceMaps: false` and `experimental.serverSourceMaps: false` (2026-10-29) · `experimental.webpackMemoryOptimizations: true` (Next.js 15 and later) (2026-10-29) · `next build --experimental-debug-memory-usage` (2026-10-29)

Out of memory after the deploy

The running app has its own limit, separate from the build: 512 MB on Starter and 2 GB on Live. It is a hard cap. Past it, the kernel kills the process, and the Traffic & Memory chart on the project overview marks the moment as Out of memory, killed. The same chart draws memory against the limit, with each build marked, so a steady climb between deploys (a leak) looks different from jumps that follow traffic (real need).

Canner also warns before it gets there. When an app stays at or above 90% of its memory limit for 10 minutes, the organization’s owner gets an email, at most once per deploy and once a week per project.

To make Node collect garbage harder before the kernel steps in, set a heap limit below the app’s memory, for example --max-old-space-size=1536 for a 2 GB app. Add NODE_OPTIONS in Env Vars with the scope runtime only: that scope reaches the running app but never a build, so it can’t cap your build’s heap. Raising the limit won’t fix a leak; it only moves the crash later.

Adding memory: App RAM or Dedicated RAM

On a paid plan you can add memory to a project without changing plan. The two add-ons behave differently:

App RAMDedicated RAM
Price$4 / GB / month$19 / GB / month
GuaranteedNo: pooled memory. When the server is busy the app slows down, but isn’t cut offYes: reserved and never oversold
Build memory+1 GB for each GB assignedUnchanged
Good forA site or API that needs more headroomPostgres, AI workloads, anything that needs steady performance

Questions

What is the difference between exit code 134 and 137?

134 is 128 + 6 (SIGABRT): Node aborted itself at its heap limit and printed JavaScript heap out of memory. 137 is 128 + 9 (SIGKILL): something outside the process killed it, usually the kernel when a container passes its memory limit. Raising --max-old-space-size can fix the first and worsen the second.

Should I set NODE_OPTIONS=--max-old-space-size on Canner?

Not for builds: Canner already sizes the heap to the build’s memory budget, and a lower value of yours wins and causes the error. For the running app, a value below its memory limit, scoped runtime only, is reasonable.

How much memory does a build get on Canner?

Up to 4 GB on Starter and 6 GB on Live. On Live, App RAM adds 1 GB of build memory per GB assigned. Once a month, a GitHub production build that runs out of memory is retried automatically with the next tier’s memory.

Will more memory fix a memory leak?

No. It delays the crash. If memory climbs steadily between deploys and drops only when the app restarts, look for the leak with a heap snapshot first.

Builds sized for real projects.

Up to 4 GB of build memory on the free plan, with the peak printed in every log.