When something breaks
App crashes with Killed or exit code 137: out of memory
In short
The word Killed in your logs or exit code 137 almost always means the app went over its memory limit and the system forcibly stopped it. 137 is 128 plus signal number 9, SIGKILL: the process did not exit on its own, it was killed, which is why the logs usually show no error message. The usual memory hogs are a neural network model, a big file loaded into pandas at once, a browser for Selenium, or a list that keeps growing forever. Cut down what the code uses first, and if the app is heavy by nature, move to a plan with more memory.
- Exit code 137 equals 128 plus 9: the process was stopped by SIGKILL, most often because it exceeded its memory limit.
- When an app is killed for running out of memory, Python has no chance to print a traceback, so the logs show only Killed or nothing at all.
- A CSV file takes noticeably more space in pandas than on disk, so large files are read in pieces with the chunksize parameter.
- The JavaScript heap out of memory error in Node.js is the V8 engine's own limit, not the server limit, and it is fixed differently from exit code 137.
- Several services in one docker-compose project share the same memory of the plan.
Your app starts, runs for a bit and suddenly disappears. The last line in the logs is Killed, or the project exited with code 137, or there is nothing at all: output was flowing a second ago and then silence. Sometimes it repeats in a loop: the app restarts, reaches the same point and vanishes again. There may be no bug in the code at all; it does exactly what it says, it just needs more memory than it has.
Every app on a server has a memory ceiling. When a process tries to take more, the system does not wait or ask: it stops it with SIGKILL, a signal that cannot be caught or handled gracefully. Hence exit code 137 and the missing traceback. This is known as OOM, out of memory. Below is how to find what exactly eats the memory and how to fix it.
| Memory hog | What it looks like | What to do |
|---|---|---|
| Neural network model (torch, transformers) | crashes right at startup or on the first request | use a smaller model, load it once at startup, or call the model through an API |
| Large file in pandas | crashes while reading the file | read in pieces with chunksize, keep only needed columns with usecols, set dtype |
| Selenium or Playwright with Chrome | crashes after a few pages | headless mode, one browser for the whole script, close pages and call driver.quit() |
| Leak in a loop | runs for hours, then crashes, again and again | cap caches and lists, close connections and files, do not keep history in memory |
| Images and video | crashes on large uploads | downscale images before processing, handle files one at a time, write results to disk |
| Building a frontend, Rust or Java | fails during the build, not while running | build the frontend locally and upload the output folder; for Rust reduce build parallelism |
| Several services in docker-compose | the hungriest service goes down | drop unneeded services or move the database to an external service |
Confirm that memory is the problem#
Look at when exactly the app dies. Right at startup points to loading a model, a big file or a heavy library. After hours of work, with memory climbing steadily before that, points to a leak. Exit code 137 can have other causes too, for example the wrong file being started and then forcibly stopped, so double check that your actual app is launched and not a helper script like init_db.py.
Find what takes the most#
Run the app on your machine and watch its memory in the task manager or with a command like top. In Python the built-in tracemalloc module shows which lines of code allocate the most memory. The culprit is often found in minutes: one line that reads the whole file, creates the model or collects results into a list. That line is what you fix, not the whole app.
Process data in pieces#
Large files do not have to be loaded whole. In pandas, read_csv has a chunksize parameter that reads the file in pieces, so only one piece sits in memory at a time, and usecols keeps only the columns you need. API responses and database exports are also better handled page by page, writing results straight to disk or the database instead of piling them up in a list. This is usually a single change that cuts memory use several times over.
Make browsers and models lighter#
If your project uses Selenium or Playwright, run the browser headless, without a window, keep one instance for the whole script and always close it with driver.quit(), because every forgotten browser keeps holding memory. Neural networks follow a similar rule: load the model once at startup rather than per request, and pick a lighter version. If the model still does not fit, calling it through the provider's API is simpler than hosting it yourself.
Plug leaks in long-running code#
A bot or script that runs for days crashes in a loop if something in it grows without limit: a dictionary with every user's history, an unbounded cache, a list of processed messages, database connections that are never closed. Cap the cache size, keep history in a database rather than in memory, and close files and connections with with blocks. After the fix, watch memory for a few hours: it should level off instead of climbing.
If the app truly needs more, pick a bigger plan#
Some apps need a lot of memory by their very nature: a model you cannot replace, a big dataset, several services side by side. Then optimization hits a ceiling, and the right answer is a plan with more memory. The memory of each plan is listed on the pricing page. A failure during the build rather than at runtime is a separate case, usually solved by building the project in advance or reducing build parallelism.
Killed and exit code 137 are not a mysterious glitch but a direct message: the app ran out of memory. Most of the time one change is enough: read the file in pieces, close the browser, load the model once. On Netrun an out-of-memory crash is visible right away: the project page says the app ran out of memory and shows the limit, the project restarts on its own, and logs and load are in your dashboard. If the app is heavy by nature, the Pro and Max plans have more memory, and in a docker-compose project that memory is shared between services. Try Netrun.
Common questions
What does exit code 137 mean?
It is the code a process exits with when it is stopped by SIGKILL: 128 plus signal number 9. Most often the system sends that signal when an app exceeds its memory limit. The process has no chance to write anything at that moment, so the logs usually have no details.
Why does it work locally but crash on the server?
On your computer the app has gigabytes of free memory, while on a server it has a fixed ceiling. Code that happily eats a couple of gigabytes on a laptop hits the limit on the server and gets stopped. Check how much memory the app takes on your machine and compare it with your plan's limit.
Can I catch running out of memory in code and handle it?
Hardly. Python's MemoryError is rare, because the system usually kills the process before Python can raise it. It is more reliable to avoid overuse in the first place: read data in pieces, cap caches and keep an eye on memory.
What about the JavaScript heap out of memory error?
That is the Node.js engine's own limit, and it can trigger before the server runs out of memory. It is raised with the --max-old-space-size flag, but the value has to stay below your plan's memory limit, otherwise you trade this error for exit code 137. If it happens while building a frontend, it is easier to build locally and upload the output folder.
Will automatic restarts fix it?
A restart brings the app back, but if the cause is a leak, it will crash again after the same amount of time. That is fine as a safety net, not as a fix. If crashes keep repeating, find what grows in memory or move to a bigger plan.
What happens if my app crashes?
We watch over projects and restart them if they fail. The status and the logs appear in your account straight away, and we send a notification only if the app has not come back within an hour: short interruptions are not worth disturbing you over.
Where can I see the logs and status of my project?
The project page shows the status, the logs and the event history — together they show what is happening with the project right now. The log view also reaches further back: scroll up and earlier lines load on their own.
What is different about the Pro plan?
On the Pro plan your project runs around the clock: a website does not sleep and responds instantly, with no pause to wake up, while a bot or a background script keeps running with no time limit. On top of that, Pro gives more memory, CPU and disk space, and a Pro website can use your own domains — as many as you need, each with HTTPS.