An import script started overnight has stopped halfway by morning, and the log contains a single word: Killed. Or a large report page in an online shop returns a 500 error instead of opening. The cause is often the same: a process asked for more memory than it was allowed and the system stopped it. This is called OOM, "out of memory". Here is how it happens, how to tell it apart from other errors and how to make code use less memory.
Two different memory limits
The first is PHP's own memory_limit, which caps a single PHP script. When a script exceeds it, PHP stops and logs a clear message:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 20480 bytes) in /var/www/USER/data/www/example.uz/report.php on line 42
The message names the file and line, and 134217728 bytes is 128 MB, the limit the script reached. The second is the RAM allocated to your whole account, counting all PHP, Python, Node.js and other processes together. When the total exceeds it, the operating system kills a process, usually the largest, without warning. The program has no chance to log anything: the terminal shows Killed and a web page ends with a 500 or 503 error. That is an OOM kill.
Recognising OOM
A Python or Node.js script stops mid-run with exit code 137, meaning it received SIGKILL from outside. A long-running bot restarts on its own from time to time. The site works normally but fails during big exports, image uploads or heavy reports, while the memory line in the panel's resource graph touches the ceiling. These commands show who is using memory:
# Your processes sorted by memory (RSS, in kilobytes)
ps -u "$USER" -o pid,rss,etime,cmd --sort=-rss | head
# Peak memory used by a script
/usr/bin/time -v python3 import_orders.py 2>&1 | grep "Maximum resident"
# If the command ended with "Killed", the exit code is 137
echo $?
/usr/bin/time -v reports peak memory during a run, which you can compare with your plan's RAM limit.
Why memory runs out
The most common mistake is loading a whole file or table at once; a 100,000-row Excel file takes several times its disk size in memory because every value becomes an object. Image processing is another: a phone photo of a few megabytes expands to tens of megabytes uncompressed. Python apps under Gunicorn keep a full copy of the app in each worker, so four workers mean four times the memory. Finally, memory leaks, such as a global list that grows on every request, fill memory slowly until the process is killed.
Example: a restaurant bot in Bukhara
A Bukhara restaurant ran a Python Telegram bot for orders. Each evening the manager uploaded a monthly Excel report, and as the file grew the bot started dying with Killed. It opened the whole file in memory and collected all rows into a list before writing them. Switching to row-by-row processing fixed it:
from openpyxl import load_workbook
# read_only=True does not load the whole file into memory
wb = load_workbook("buyurtmalar.xlsx", read_only=True)
ws = wb.active
for row in ws.iter_rows(min_row=2, values_only=True):
save_order(row) # write each row to the database straight away
wb.close()
Peak memory dropped sharply and the bot stopped crashing, with no plan upgrade needed.
Saving memory
In PHP, run large exports in batches:
// Process in batches of 500 instead of loading everything at once
$offset = 0;
do {
$rows = $db->query("SELECT id, name, total FROM orders ORDER BY id LIMIT 500 OFFSET $offset")->fetchAll();
foreach ($rows as $r) { fputcsv($out, $r); }
$offset += 500;
} while (count($rows) === 500);
For Python web apps, match the worker count to real load and, if there is a leak, recycle workers periodically:
gunicorn app:app --workers 2 --max-requests 500 --max-requests-jitter 50
This recreates each worker after roughly 500 requests, releasing leaked memory, but it is a workaround and the leak should still be found. Raising memory_limit only lifts the PHP cap, not the account's RAM limit, and can even bring an OOM kill sooner.
When you need more RAM
If the code is optimised, workers are sized correctly and there is no leak, the application genuinely needs more memory. Always-on bots and Node.js or Python apps are often better on a VPS, where the memory is yours alone. You can change your plan or order a VPS in the sayt.uz cabinet.