Skip to main content

Memory & Resources

Every app runs with a CPU and memory limit you choose when you create it (and can change any time in Settings → Resources). Picking the right memory size is the single most common cause of a deploy that builds fine but then fails at the release step — so it's worth understanding.

The default is 512 MB

New apps default to 512 MB of memory. That's plenty for a small API or a static-ish app, but heavier frameworks can exceed it the moment they run database migrations or boot. The wizard now recommends ≥ 1 GB for detected Laravel, Django, Rails and Symfony apps for exactly this reason — you can still change it.

"Release phase ran out of memory (exit 137)"

If a deploy fails with a message like:

Release phase ran out of memory — the post-deploy step (e.g. migrate) was killed (exit 137) after exceeding this app's memory limit (512 MB).

…it means your post-deploy / release command (usually php artisan migrate --force, python manage.py migrate, etc.) used more memory than the app's limit, so the kernel killed it. exit 137 is the universal signal for an out-of-memory kill (128 + SIGKILL).

Why the release step and not normal serving? Frameworks like Laravel (especially with Filament) or Rails load every service provider / the full application kernel to run migrations — that boot is the memory peak, often well above what the app needs once it's just serving requests.

The fix: raise the Memory Limit in Settings → Resources and redeploy. 1 GB is a good first step for most Laravel/Django/Rails apps; very large apps (many migrations, big seeders, Filament with lots of resources) may want 2 GB.

Release gets extra headroom automatically

Vessl already gives the release/migrate step more memory than steady-state serving (up to roughly double, capped at 4 GB). So many apps deploy fine at 512–1024 MB even if the migrate peak is higher — the long-running container then keeps your chosen, tighter limit. If you still hit exit 137, your app's peak is above that headroom — raise the limit.

"Build ran out of memory (exit 137)" — different from the above

If the failure happens during the build (not after it), with a message like:

Build ran out of memory (exit 137): a build step (e.g. next/vite build, gradle, go build) was killed when the server ran out of free RAM.

…this is a different limit from the one above. The build runs in Vessl's shared builder, which is bounded by the server's free RAMnot the app's Memory Limit (that setting only caps the long-running app container). So raising the Memory Limit does nothing for a build OOM.

Common culprits are memory-hungry frontend bundlers (Next.js, Vite, webpack) and JVM builds (Gradle/Maven). The fix is one of:

  • Deploy on a server with more RAM (or free up memory on the host — check what else is running there).
  • Shrink the build's footprint — e.g. cap Node's heap with NODE_OPTIONS=--max-old-space-size=512, reduce build concurrency/parallel workers, or split a monorepo build.
  • Build a smaller image — move heavy one-off work out of the build step, or use a Dockerfile with a leaner build stage.
Build memory ≠ app Memory Limit

The Memory Limit in Settings → Resources bounds your app while it runs. The build is bounded by the server. A build OOM means you need a bigger server (or a lighter build), not a higher app limit.

Watching memory at runtime

The app's Overview → Resource Analytics panel shows live memory used vs. your limit. When usage climbs past 85 % of the limit, Vessl shows an amber warning — a heads-up that the app may get out-of-memory-killed while running (the runtime version of the same exit 137). If you see it regularly, raise the memory limit or reduce the app's memory use.

How much do I need?

StackSuggested start
Static / small API / Go256–512 MB
Node.js / Next.js512 MB – 1 GB
Laravel, Django, Rails, Symfony1 GB
Laravel + Filament, large data migrations1–2 GB

These are starting points, not hard rules — watch the Resource Analytics panel after your first deploy and adjust.