An app that runs fine for a while and then suddenly vanishes — no stack trace, just gone — is usually out of memory. It's one of the few failures that doesn't explain itself in the usual way, so this guide is about spotting it, then trimming your app back under the limit.
Recognizing an OOM kill
When your app uses more memory than the server has, the system steps in and kills it. It doesn't ask nicely, so the signs are blunt rather than descriptive:
- The console shows
Killed, often with exit code 137. - There's usually no application error at the point of death — your code didn't throw, it was terminated from outside. (Contrast that with an ordinary startup failure, where the console names the error.)
- It tends to happen under load — more users, a big request, a large file — rather than at idle. An app can be fine for an hour and die the moment traffic spikes.
🎯 Good to know: If you see
Killedor exit code 137, stop hunting for a bug in your logic — you're over the memory limit.
Why it happens on free
A free Falix server has 2.5 GB of shared memory. That's plenty for a bot, a small website, or an API — but a memory-hungry app (large in-memory datasets, image or video processing, big caches, many heavyweight libraries loaded at once) can blow through it. There are two honest options: use less memory, or move to premium, where you get your plan's own memory instead of the shared free pool. If your app genuinely needs the headroom, premium is the real fix — the tips below only take you so far.
See how much you're using
You don't have to guess. Open the Console page: the RAM resource card shows your live memory use against your limit, updating as the app runs, alongside the CPU and network cards. Watch it while you reproduce the problem — that one card tells you whether you're slowly creeping toward the limit or slamming into it, which is exactly how you tell the two patterns below apart.
🎯 Good to know: On premium, the Monitoring page adds a longer memory timeline and a health score, so you can see usage trend over hours instead of seconds.
Leak, or just too big?
Two different problems hit the same wall, and the fix differs. Watch the RAM card while it happens and you'll see one of two shapes:
| Pattern | What it is | The fix |
|---|---|---|
| Memory climbs steadily, killed even at idle | A leak — something accumulating that's never released (an ever-growing array, cache, or event listeners) | A bug to find and fix |
| Memory is fine, then spikes under a burst of work | Peaking — using too much at once for the job | Do the work in smaller pieces |
The habits below help with both.
Using less memory
Most savings come from the same few habits, whatever the language:
- Carry fewer heavy dependencies. Every big library you import costs memory before your app does anything useful. Drop the ones you don't need, and prefer a small library over a giant framework when the giant one is overkill.
- Stream instead of loading whole files. Reading a large file (or a big database result) fully into memory is the fastest way to spike usage. Process it in chunks — read a line or a block, handle it, move on — so only a slice is in memory at any moment.
- Bound your caches. An in-memory cache or a list that only ever grows is a slow-motion OOM. Cap its size, or expire old entries, so it can't swell without limit. Same goes for logs and buffers you keep "just in case".
- Offload big data to a database. Rather than holding everything in memory, keep it in a database and query only what you need. See Add a database.
Node
Node keeps a lot in its heap. Beyond the habits above, watch for unbounded arrays and event listeners you never remove — they pin memory that can't be freed. If you're loading big JSON files, stream-parse them instead of calling JSON.parse on the whole thing at once.
Python
Python's per-object overhead adds up fast on large collections. Prefer generators over building giant lists, iterate over database results instead of fetching them all at once, and be wary of loading a whole dataset (a big CSV, say) into memory when you could process it row by row.
Java
The Java application runs your jar with the JVM's default sizing — no build or tuning happens on the server, and for most apps the defaults are fine. A large Java app that needs its heap sized deliberately runs into a limit here: changing the JVM's memory flags means editing the startup command, which is a premium feature. If that's you, premium is the path — but treat any specific flag as something to test against your own app rather than a guaranteed fix. There's no magic number that makes a too-big app fit into too little memory.
When to just go premium
Some apps are simply bigger than 2.5 GB of shared memory allows, and no amount of trimming changes that. If you've streamed your files, bounded your caches, and dropped the dead weight, and you're still getting killed under normal use, that's the signal to move to premium rather than fight it.
⚠️ Heads up: The free timer is separate from memory — a server can stop because its session ran out, which is not an OOM at all.