Lewis' Blog Tales from the trenches of information technology

25Jun/132

WordPress, WooCommerce, and the elusive WP_MEMORY_LIMIT issue

Download PDF

WooCommerce (and likely some other WordPress plugins - and non-WordPress apps - tend to be rather microcosmic when determining system settings. Case in point: the PHP memory limit.

Prior to PHP 5.2.1, the per-script memory limit available was set at compile time (via the --enable-memory-limit option). With 5.2.1, we got the php.ini directive:

memory_limit <integer>

to set this value at run time 1. In fact, it can even be overridden (if the server admin allows) so that specific apps may set it themselves, thus allowing for greater granularity across all running PHP applications on the server, even under the same instance of the engine.

WordPress has had the ability to tweak this value since version 2.5 (that's WordPress 2.5, not PHP 2.5!) via the WP_MEMORY_LIMIT variable, settable in /wp-config.php 2. The trick is where to add the variable so that it actually does some good (or, for the purposes of this discussion, so that some less-than-intuitive plugins may actually see the value and stop complaining).

The interaction between the php.ini setting and the WordPress setting is essentially that the WP setting should override the php.ini setting, just as an ini override in, say, Apache's conf or .htaccess would.

The WordPress CODEX specifically states:

[...] By default, WordPress will attempt to increase memory allocated to PHP to 40MB (code is at beginning of wp-settings.php), so the setting in wp-config.php should reflect something higher than 40MB.

WordPress will automatically check if PHP has been allocated less memory than the entered value before utilizing this function. For example, if PHP has been allocated 64MB, there is no need to set this value to 64M as WordPress will automatically use all 64MB if need be.

So, assuming php.ini says something like:

memory_limit = 256M

WordPress should be satisfied and not override that value with what is hard coded into /wp-includes/default-constants.php (the quoted 40MB and 64MB figures, respectively, for single and multi-site installations). However, some plugins seem to believe only what is set in WP_MEMORY_LIMIT.

While working with a colleauge to set up a new WooCommerce-enabled site on my server, I happened to check out WooCommerce's System Status page, which said:

WP Memory Limit:     40MB - We recommend setting memory to at least 64MB

Hmmm...

Okay. So, in /wp-config.php, I added:

define('WP_MEMORY_LIMIT', '256M');

When the warning didn't change, however, I went looking a little deeper, and realized that I had inserted it at the end of the file. The statement immediately above it read(s):

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

and, of course, in wp-settings.php, there is a call to:

require( ABSPATH . WPINC . '/default-constants.php' );

which, in turn, has this nice little bit of code:

function wp_initial_constants( ) {
    global $blog_id;
    // set memory limits
    if ( !defined('WP_MEMORY_LIMIT') ) {
        if( is_multisite() ) {
            define('WP_MEMORY_LIMIT', '64M');
        } else {
            define('WP_MEMORY_LIMIT', '40M');
        }
    }

which simply states (for those unaccustomed to reading PHP):

If we haven't already set WP_MEMORY_LIMIT, and we are using the MultiSite WordPress, then set WP_MEMORY_LIMIT to 64MB; otherwise, if it's not already set and we are not using MultiSite, set it to 40MB.

My initial inclusion of the line at the bottom of wp-config.php was too late to be recognized, as we had already included default-constants.php by the time we read down that far in wp-config.php. So, I moved it up six lines and problem solved.

Now, what's of greater importance to realize here is that what I did was simply quiet a nonsensical warning message. PHP was already configured for 256MB maximum memory per script, and WordPress knows enough not to monkey with that. WooCommerce, however, simply sees that WP_MEMORY_LIMIT has been defined as 40MB, and throws a warning. Apparently, it does not actually perform an ini_get() request to ask the engine how much memory has been configured.

In fact, this (the WP_MEMORY_LIMIT issue) has been mentioned in several places, including this bug in the WooCommerce tracker. There is also at least one mention on the net of hacking default-constants.php, which I do not recommend (it's called "default-constants.php" for a reason, and in any case, an upgrade at any time the WordPress folks deem necessary to change the default value will likely overwrite or remove the hack).

  1. http://www.php.net/manual/en/ini.core.php#ini.memory-limit
  2. http://codex.wordpress.org/Editing_wp-config.php
Comments (2) Trackbacks (0)
  1. Hey Lewis,

    Just wanted to thank you for the great article.  I've been wondering why the warning message continues to appear and did the exact same thing (appended the line 'define('WP_MEMORY_LIMIT', '256M');' at the end) and I remember there was another workaround where I had to modify another configuration file that did the trick but this was much simpler! Thanks.

    • Thanks for the compliment, Frank. Glad this got you to the same point with a little less fuss than the other procedure you mentioned. I have a hunch you may have been directed to edit default-constants.php, which was the first solution I stumbled into (and which prompted me to look further).

      Cheers


Leave a comment

No trackbacks yet.