Loading...


Related Products


Date Published: July 17, 2024

Conditionally increasing memory limits for Drupal and Drush

Issue

When navigating to a Drupal page, or running drush, you encounter an "Allowed memory size of xxxxxx bytes exhausted" type error.
An example of this is:

Error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 8192 bytes) in /home/meosch/l2m.ch/releases/20171229-022429/docroot/core/lib/Drupal/Core/Extension/InfoParserDynamic.php, line 22


Some pages on your Drupal website (such as /admin/... or /reports/... pages) can require additional resources to run. However, increasing these resources globally can decrease your website's overall performance.

Instead of making global changes, you can increase resources conditionally on a case-by-case basis in your website's settings.php file. To do this, add a code snippet that describes your memory change in the PHP settings region, under the other PHP ini_set() calls.

For a Drupal application, not only can the website be impacted, but the associated Drush tool may also require the increase of memory when executed.

Note

Be sure to add any specific changes after the global ini_set. If the global ini_set is located after your change in the file, it will override the changes made preceding it in the file.

 
Warning

If you set a higher PHP memory limit in your settings.php file than what was used to calculate the available PHP processes, you risk making your entire website unavailable, not just the webpage that was displaying an out-of-memory error.

Resolution

This error is encountered when Drupal or drush attempts to use more memory than it has been allocated from the PHP configuration file, php.ini.
For drush using PHP 8.1, it is generally found in /usr/local/php8.1/etc/cli/php.ini).
The memory amount allocated is defined by the memory_limit parameter.
In the php.ini file this would be an example of the setting:
memory_limit=512M
 

Increasing the memory limit for Drupal

To modify the memory_limit value for Drupal, you need to use the PHP ini_set() function.
This is used in your website's settings.php file.

For Drupal 7

Here's a code snippet example which determines if you're on an admin path, and if so, increases the memory limit, leaving the default memory limit in place for other pages on the website:

if (isset($_GET['q']) && strpos($_GET['q'], 'admin') === 0) { 
    ini_set('memory_limit', '256M'); 
}

For Current Drupal

Here's a code snippet example which determines if you're on an admin path, and if so, increases the memory limit, leaving the default memory limit in place for other pages on the website:

if (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], 'admin') !== false ) {
  ini_set('memory_limit', '256M'); 
}

 

Additional Examples for Current Drupal

A more complex example

A slightly more complex example of this sets limits for multiple pages. If you're performing tasks that are not on the /admin/... path (such as adding or editing content), you can conditionally increase the memory on the /node/... paths, which have add or edit (as well as the admin paths) to 256M, using the following code snippet:

if (
    isset($_SERVER['REQUEST_URI']) &&
    (strpos($_SERVER['REQUEST_URI'], 'admin') !== false ||
    strpos($_SERVER['REQUEST_URI'], 'node/add') !== false ||
    strpos($_SERVER['REQUEST_URI'], 'node/') !== false) &&
    preg_match('/^node\/[\d]+\/edit/', $_SERVER['REQUEST_URI']) === 1
  ) {
  ini_set('memory_limit', '256M');
}

 

Increase memory for AJAX paths

If you're receiving an out-of-memory error when uploading a file into a specific field using AJAX, you can specifically increase the memory limit for the AJAX path as well by using a code snippet similar to the following:

if (
    isset($_SERVER['REQUEST_URI']) &&
    strpos($_SERVER['REQUEST_URI'], 'file/ajax/field_thumbnail_image/') !== false
{
   ini_set('memory_limit', '256M');
}


Using an array for multiple paths

The following example separates the code into more maintainable pieces, enabling you to add and remove paths more easily by defining them in a variable that is passed to the memory limit function:

$admin_paths = array(
  'admin',
  'crop',
  'node/add',
  'node/%node/edit',
);

// standardize node edit paths for validation
$current_path = preg_replace("/\d+/", '%node', $_SERVER['REQUEST_URI']);

foreach ($admin_paths as $admin_path) {
  if (strpos($current_path, $admin_path) === 0) {
    ini_set('memory_limit', '256M');
  }
}


For Acquia Cloud Site Factory Drupal

If your websites are hosted on Acquia Cloud Site Factory, you cannot directly modify your websites' settings.php files. Instead, you can use Factory hooks. This means, that you add the conditional memory code, as given above, into a PHP file in your factory-hooks/pre-settings-php directory.

For more information, see "Hooks in Site Factory " in the Acquia Cloud Site Factory documentation and an example on how to increase the memory limit on Site Factory.
 

 

Why set specific paths?

Although Acquia recommends that you tune your website's memory use for specific paths, specific reasons for how this can be helpful depend on your website's hosting environment.

If you host your website on Acquia Cloud, updating the limit for the entire website takes priority over your server tuning and the PHP memory limit set in the Acquia Cloud UI. When Acquia configures server tuning, we calculate how many PHP processes could run simultaneously on the server, given the available memory on that hardware with each PHP process using the maximum amount of memory allocated for PHP.

Although PHP processes do not automatically allocate or consume the full amount of memory set as the PHP memory limit, if the PHP processes attempt to consume more memory than is available on the server hardware, the server as a whole will eventually reach an out-of-memory (OOM) state. The Linux kernel then attempts to kill the processes that are using up memory to resolve the issue. These processes can include MySQL, which can cause outages for your website and any websites sharing your server.

By limiting the memory increase to specific paths, you significantly reduce this risk. However, you should still keep the conditional memory increases as low as possible to reduce the risk that multiple requests for these paths would be greater than the total memory capacity of the server.


Module alternatives

Memory limit policy is a base module to override the default PHP memory_limit based on various constraints.

 

Increasing the memory limit for Drush

The memory limit for a running the drush command can be changed by overriding different settings.

To verify that the memory limit has been set to the intended value, see Verifying the current memory limit set for Drush commands section below.

Applying memory override to Drush

The memory limit can be set either at the command line, by modifying the Drupal application's settings.php file, or using a drushrc.php file.

You can override the memory used for Drush operations in one of three ways:

  1. as a one-time override when running the drush command
  2. as a permanent override in settings.php
  3. as an entry in drushrc.php (this is only for drush versions 7 and 8)

1. One-time override

You can implement an override in one of two ways:

  1. use the PHP CLI " -d" option
  2. prefix a drush command with a "PHP_OPTIONS=..." statement to set a memory limit
 
Note

This will only work if you do NOT have other memory overrides set up.

For Current Drush

# Set the Drush memory limit to 1024M
# NOTE: This will only work if you do NOT have other memory overrides set up.

  php -d memory_limit=1024M /mnt/www/html/path/to/drush <command>

# For example, for examplesite.prod using PHP 8.2 and vendored drush
# the command would look like:

  php -d memory_limit=1024M /var/www/html/examplesite.prod/vendor/drush/drush/drush <command>

For Drush 7 and 8

# Set the Drush memory limit to 1024M
# NOTE: This will only work if you do NOT have other memory overrides set up.

  PHP_OPTIONS='-d memory_limit="1024M"' drush <command>

 


2. Permanent override

The following snippets, when added to your settings.php file, will change the memory limit available to Drush commands:

For Current Drush
Drush was completely rewritten in version 9, in which the options that would allow it to set memory settings for your php environment were removed. (See this issue for details). 

Instead of making changes to the drush configuration, the memory for PHP command line tools, such as drush, can be increased with a conditional memory limit increase in your application's settings.php file, using the PHP_SAPI constant.

if (PHP_SAPI === 'cli') {
  ini_set('memory_limit', '512M');
}

For Drupal 7
For Drupal 7 installations, use the drupal_is_cli() API.

if (drupal_is_cli()) { 
  ini_set('memory_limit', '256M');
}
 

3. For Drush 7 and Drush 8 use the drushrc.php file

If you find that you are seeing an out of memory error when running drush commands for versions 7 or 8, you may need to increase the memory limit via a drushrc.php file.

By default, Drush is configured to use the value set by php.ini, that is, 512 MB of memory on Acquia Cloud for stock php-cli builds. Custom builds of PHP can have a different default value. Occasionally, however, you can have scripts, updates, or other commands that require more memory than the default amount.

To determine your environment's default memory settings for your PHP build, run the following php command:

php -r 'print ini_get("memory_limit") . "\n";'

The following steps outline how to increase the memory limit for Drush 7 and 8 by creating a custom drushrc.php file which is used by drush using the --config flag.

1) Open a command prompt window. This step assumes that drush has been installed using composer .
Navigate to /<path_to_drush>/vendor/drush/drush/examples.
 
2) From the examples directory, copy the example.drushrc.php file and add it to your repository on the same level as docroot in a directory called drush.

3) Rename the copied file to drushrc.php.

4) Add the following line of code, with your desired increased memory value, to the file to expand the memory limit for Drush (if it's not already set to 512M):
ini_set('memory_limit', '512M');
5) For your local development environment, you can now put your new file into your home ~/.drush directory.
In order to apply changes to your Acquia code base, enact the following steps.
You can commit the new file and directory to allow it to be accessible by Drush commands remotely.
For example, if your application directory is mysite, create a directory called drush in the root of the repository and the file would be placed in that directory.
For example:
/mysite/drush/drushrc.php
After this is done, and you sign in to your Acquia Cloud server using SSH, you can run Drush, adding the --config flag to use this new memory limit (and any other future drush configs that may be desirable).
From running drush topic core-global-options the --config option defines the configuration file to use:
-c </path/file>,       Specify an additional config file to load.
                        See example.drushrc.php.
 --config=</path/file>
So, for the example above, the command to use would be:
drush --config=/mysite/drush/drushrc.php
And on the Acquia platform:
drush --config=/var/www/html/mysite.dev/drush/drushrc.php --root=/var/www/html/mysite.dev/docroot status
This tells Drush to look in the requisite directory for any resource configuration (rc) files and to call them.

For other examples of items you can add to drushrc.php see example drush aliases.
 

Verifying the current memory limit set for Drush commands

You can confirm your memory limit settings for Drush by running the following command to retrieve the PHP configuration value:

drush php-eval 'print(ini_get("memory_limit")."\n");'

See PHP ini_get() for more details.

Note

Using the command php -i will not reflect the correct values for memory_limit, as the command line PHP uses a different configuration.

 


 

Did not find what you were looking for?

If this content did not answer your questions, try searching or contacting our support team for further assistance.

Back to Section navigation
Back to Site navigation