Guides

«Allowed memory size exhausted»: how much memory does PHP really need

Where memory_limit gets changed, who wins between php.ini, pool and code, and why raising the limit to 2 GB hides the problem rather than solving it.

UptimeMag editorial team · 9 October 2026 · 5 min read

«Allowed memory size exhausted»: quanta memoria serve davvero a PHP

Quickest check (30 seconds)

The site is down with a 500 error. Before touching any configuration, look at the exact wording of the error. If the log shows a line like PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate X bytes) in /path/file.php on line NN, you already have two pieces of information: the current limit in bytes (134217728 = 128M) and the file/line where the script stopped. That line is the starting point for everything, not a symptom to be ignored by bumping up a number.

On Ubuntu 24.04 with Nginx and PHP-FPM, the log to open is the pool's log, usually /var/log/php8.3-fpm.log (the name changes depending on the installed PHP version). On cPanel it's the same PHP error log visible from Metrics → Errors or in the file specified by the domain's error_log directive. On Plesk it's the domain log under Websites & Domains → Logs. In all cases, according to the official PHP-FPM documentation the default log path is configurable via the error_log directive, with a default value of #INSTALL_PREFIX#/log/php-fpm.log error_log string: Path to error log file. Default value: #INSTALL_PREFIX#/log/php-fpm.log. — on Debian/Ubuntu distributions this prefix becomes /var/log/.

What the error means, in one line

PHP has a memory ceiling that no single script can exceed on its own. When it's exceeded, PHP stops the script immediately to avoid bringing down the whole server: it's not a system crash, it's a safety brake that did its job.

Where memory_limit gets changed, and who wins

There are three levels, and they aren't alternatives: they stack according to a precedence hierarchy.

1. php.ini (server or PHP version). The global configuration file. The default value, if left untouched, is 128M: memory_limit int: This sets the maximum amount of memory in bytes that a script is allowed to allocate. This helps prevent poorly written scripts for eating up all available memory on a server. Note that to have no memory limit, set this directive to -1. This is the starting value that the other two levels act upon, unless they're blocked.

2. FPM pool or hosting panel. On Ubuntu 24.04 with PHP-FPM, the value is set in the pool file (e.g. /etc/php/8.3/fpm/pool.d/www.conf) with a line such as php_admin_value[memory_limit] = 256M, after which you check the syntax and reload the service: bash sudo php-fpm8.3 -t && sudo systemctl reload php8.3-fpm On cPanel the same result is achieved via Software → MultiPHP INI Editor, where the directive is described as the memory ceiling in MB available to the script: memory_limit - Maximum amount of memory in MB available to a php script. This limit prevents overloaded scripts from allocating available server memory. On Plesk the file path changes depending on the installed PHP version: 7.4 /opt/plesk/php/7.4/etc/php.ini PHP 8.0 /opt/plesk/php/8.0/etc/php.ini PHP 8.1 /opt/plesk/php/8.1/etc/php.ini PHP 8.2 /opt/plesk/php/8.2/etc/php.ini PHP 8.3 /opt/plesk/php/8.3/etc/php.ini PHP 8.4 /opt/plesk/php/8.4/etc/php.ini. and the default remains 128M: The default setting in Plesk is 128M. After saving from the panel there's no need to restart manually: After the settings are saved, the web server automatically reloads the configuration using a graceful restart, so that existing requests are paused rather than terminated.

3. The application, at runtime (ini_set('memory_limit', '512M')). This is where it's decided who wins: if the value has been fixed with php_admin_value in the pool, the code can no longer change it. The official documentation states as much: php_admin_value name value: Sets the value of the specified directive. This can not be used in .htaccess files. Any directive type set with php_admin_value can not be overridden by .htaccess or ini_set(). If instead the pool uses php_value (without "admin"), the script can still raise it with ini_set(). So: if you've put ini_set() in your code and the error persists unchanged, the number one suspect is that someone upstream has locked the value with php_admin_value.

Why 2 GB doesn't fix it, it hides it

Raising the limit makes the error disappear almost every time — until the script encounters a dataset large enough to exhaust that too. In the meantime, you've only pushed the problem further down the line and increased the cost: more allocatable RAM per FPM process means fewer pm.max_children processes for the same amount of server RAM, and therefore fewer concurrent requests that can be handled.

The correct way to find out what's actually consuming memory is to measure, not guess. The memory_get_peak_usage() function returns the peak memory allocated by the script up to that point, in bytes, and accepts an optional parameter to include memory reserved by the system: Returns the peak of memory, in bytes, that's been allocated to your PHP script. Placing it before and after suspect blocks (loops over huge arrays, queries without LIMIT loaded entirely into RAM, PDF or image generation libraries) pinpoints the exact spot within minutes, instead of raising the limit at random and hoping for the best.

The lab measurement: 5,000 products in 12 MB

In our tests, an e-commerce catalogue page with 5,000 products, server-side rendered with typical product-card data (name, price, image, availability), stayed under 12 MB of allocated memory. This is our measured figure, not an industry average: it should be taken as an order of magnitude for a similar case, not as a universal threshold. If your equivalent page exhausts 256 MB, the problem isn't "too much data": it's a loop that doesn't free memory, an array growing without bound, an ORM loading the entire table instead of a single page, or a library keeping multiple copies of the same object in RAM. memory_limit did its job: it flagged a leak before it became a problem for the entire server.

How to verify it's fixed

After fixing the code, don't just check that the error no longer appears: measure the actual peak with memory_get_peak_usage(true) on the page that previously failed, and compare it against the configured memory_limit. If the measured peak reliably stays below 50–60% of the limit even under the heaviest load scenarios (exports, imports, reports), the margin is reasonable. If the peak comes close to the set limit, the fix has reduced the symptom but the cause — likely an algorithm that scales linearly or worse with the amount of data — is still there.

When it isn't your problem

If your code is lightweight, the dataset is small and the application-side memory_limit is correct, but the error still appears with low, odd numbers (e.g. exhausted at 32M when the panel shows 256M), suspicion shifts to the provider: shared hosting can apply a lower limit at the pool level or via an open_basedir/suhosin-like restriction that the client panel doesn't show. In that case, contact support and attach: the exact error text with a timestamp, the output of phpinfo() or ini_get('memory_limit') run from the very script that's failing, and the name of the domain or pool affected. Explicitly ask whether there's a limit imposed at the FPM pool level or via php_admin_value that overrides what's configured in the panel: it's the only question that lets support check the server configuration instead of sending you back to your own code.

Written with the help of artificial intelligence and checked by the editors (EU AI Act, art. 50).