Fix Wordpress "Fatal error: Allowed memory size" messages
October 27, 2011
You may (or may not) have noticed this site was down for the past few days, displaying a blank page no matter what URL was entered. After recalling that I had turned off PHP error onscreen outputting, I was presented with this lovely message:
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate XX bytes) in /some/file on line XX
This is a general PHP error, but the exact amount (
33554432 bytes) occurs very frequently on Wordpress sites. Here’s what’s happening, and how to fix it.
Every installation of PHP has an ini value called
memory_limit, which hardcaps how much memory PHP may use on any given request. There are other ini settings that dictate the memory usage for specific actions, like
post_max_size, but this one is universally applied; you can’t load anymore than what this value dictates.
I do a lot of stuff with files in PHP, so I blow this value out from it’s default of 128 MB up to 2 GB. I set this globally in my
php.ini file like so:
memory_limit = 2G
I could also set this value from inside an .htaccess file:
php_value memory_limit 2G
Since this value was set before the site even loads, imagine my surprise when PHP is telling me that the limit is now 33554432 bytes, or 32 MB. The limit was changed by a define in Wordpress called
WP_MEMORY_LIMIT. Here’s where things go awry. Wordpress tries to check the existing
memory_limit before applying it’s own terms, however the value must be set in terms of MB. Look back at my example settings; the PHP memory shorthand allows me to set in gigabytes using a “
G”. But Wordpress does a straight integer comparison to figure out if the existing setting is more/less than 32 MB. Here’s the offending code, a portion of an if statement on line 42 in
( (int) @ini_get('memory_limit') < abs(intval(WP_MEMORY_LIMIT)) ) )
What you end with in that sample is essentially
if (2 < 32), which resolves true and thus Wordpress applies it’s own default limits.
You have three options to rectify the situation: two easy fixes, plus one badass “server-baller” fix. First the easy ones. As Wordpress outlines in the article on increasing memory, simply define
wp-config.php using MB syntax. If I wanted to set it to 2 GB, it would look like this:
Your value will be honored as long as it is an integer value greater than 32, but could break if Wordpress changes it’s memory size comparison calculation.
Alternatively, I could change my the
memory_limit setting directly in
.htaccess to use MB syntax:
[php.ini] memory_limit = 2048M [.htaccess] php_value memory_limit 2048M
Realistically I would probably edit php.ini. Well, that is, I would, if I didn’t know about the badass server-baller third option, which overrides
php.ini AND prevents Wordpress (or any other site for that matter) from making any changes to the value.
Look back at my
.htaccess setting, and notice that I set the value using the command
php_value. PHP has a similar command called
php_<span class='red'>admin</span>_value, which you can use for setting all the same stuff as
php_admin_value can only be set within Apache configurations, i.e. it cannot be used inside of
.htaccess files. Furthermore, any value set using
php_admin_value cannot be overridden by any later calls to
ini_set. You can override
php.ini defaults, and lock that value in for the remainder of the request.
So back to our Wordpress example, I opened the
VirtualHost for frankkoehl.com and entered this line:
php_admin_value memory_limit 2G
Now the site will always allow a memory limit of 2 GB, no matter what. Wordpress can try and set whatever value it likes, it will never be recognized.
Note that this function requires that you have access to Apache configurations, at least the ones running your site. Most shared hosting packages won’t offer this level of access.
It’s worth mentioning that Wordpress sets a default value of 32 MB, lower than PHP’s own default of 128 MB. I disagree that such a low limit is necessary, but they are trying to be good stewards to servers everywhere, so I can see where they’re coming from.
I still have no idea why this memory issue popped up in the first place, but it gave me an excuse to share a cool configuration option that has saved me from having to scour code on several bloated, crappy sites to find obscure ini settings. I have a recent real-world example you can read about on Stack Overflow.