<p>If you just want to re-save a large number of entries <strong>without modifying them</strong>, you can run a ResaveElements task, which takes some basic parameters and re-saves all the entries that match them.</p>

<p>You can do that like this:</p>

<pre><code>// Queue up a new ResaveElements task
craft()-&gt;tasks-&gt;createTask('ResaveElements', null, array(
    'elementType' =&gt; ElementType::Entry,
    'criteria'    =&gt; array('section' =&gt; 'mySectionHandle', 'limit' =&gt; null, 'status' =&gt; null, 'localeEnabled' =&gt; null)
));

// Start running tasks
craft()-&gt;tasks-&gt;runPendingTasks();
</code></pre>

CC BY-SA 3.0
2014-07-10T17:53:33.483Z
I think this is the answer im looking for. I need to update the products programmatically and i need to set a field by product, a stock attribute based on a 3rd party service. Is this possible with this approach?
mbalparda
CC BY-SA 3.0
2014-07-10T17:59:06.907Z
@mbalparda Sorry, didn’t realize you actually needed to _modify_ the entries in the process, but I suppose that should have been obvious :) I’ll post a new answer…
Brandon Kelly
CC BY-SA 3.0
2018-04-13T09:34:11.967Z
For anyone looking for how to do this in Craft 3 (As I was): https://docs.craftcms.com/v3/updating-plugins.html#background-tasks
Mike Pierce
CC BY-SA 3.0
2014-07-08T15:00:46.523Z
2014-07-10T18:27:34.313Z
2014-07-10T18:27:34.313Z
Brandon Kelly
<p>It's likely because PHP's per-process memory limit is set too low for this particular script. I would not raise it globally using your php.ini file, but raise it right in your script on a per-process basis, right inside of your template. </p>

<p>I put together a quick plugin to do this (and set other ini_set parameters):
<a href="https://github.com/jpeacock/setini/" rel="nofollow">https://github.com/jpeacock/setini/</a></p>

CC BY-SA 3.0
2014-07-08T16:27:16.630Z
Nice! You should post that on [Straight Up Craft](http://straightupcraft.com/craft-plugins) – will have a lot of other cool uses :)
Brandon Kelly
CC BY-SA 3.0
2014-07-08T16:41:31.957Z
Worth noting that ini_set won't work if you're using fastcgi, but will if you're using mod_php.
Brad Bell
CC BY-SA 3.0
2014-07-08T16:47:34.460Z
I just changed it up to be a bit more generic. It now lets you pass in the parameter that you want to change (in this case 'memory_limit') and the value to change that parameter to.
jpea
CC BY-SA 3.0
2014-07-08T17:42:05.863Z
Nice work @jpea, I like the Twig filter approach! I built a plugin awhile back which also let's you modify ini setting, but on a larger system-wide scale: [PHP Tweak](https://github.com/lindseydiloreto/craft-phptweak). I do admire the precision of your Twig filter technique. :)
Lindsey D
CC BY-SA 3.0
2014-07-10T17:58:08.920Z
This is really good, but im having issues with a controller and not with a view. I already tried moving memory limits and it is still not working.
mbalparda
CC BY-SA 3.0
2014-07-10T18:23:53.337Z
What type of EC2 medium instance do you have? There are a bunch of types within the "medium" realm all of which have different memory offerings. http://aws.amazon.com/ec2/instance-types/ - Also, how much are you allocating to PHP? (a quick phpinfo() will show you memory_limit).
jpea
CC BY-SA 3.0
2014-07-08T15:18:26.183Z
2014-07-08T16:47:50.743Z
2014-07-08T16:47:50.743Z
jpea
<p>I've got no idea what your script is actually doing, but it sounds like it's pretty memory intensive and PHP is simply running out of it's allocated memory trying to finish executing the script.</p>

<p>Bump up the memory_limit in your php.ini file to something larger (128M, 256M, 512M, etc.) and try the script again.  Note that you may or may not have to restart your web server before the setting takes affect.</p>

<p>Another option, is to use Craft's <code>TasksService</code>, which runs these memory intensive, long running tasks in the background in small batches to avoid memory limitations like this.</p>

<p>If you're simply resaving all of the entries in the system, you can also look at triggering Craft's <code>ResaveElements</code> task, like <a href="https://craftcms.stackexchange.com/a/823/57">Brandon pointed out</a>.  If your plugin needs to do some custom logic outside of the scope of <code>ResaveElements</code>, it can create it's own task to register with Craft and run.  We don't have any documentation for that up, yet, but if you look at <code>craft/app/tasks</code> and <code>craft/app/services/TasksService.php</code> you can get a good idea of what's required.</p>

CC BY-SA 3.0
2014-07-05T15:09:44.000Z
When i was starting to code i had this issue and this answer popped everywhere. After 5 years of coding large systems, i realize this was not a good idea.
Basically you are killing your own server for a single process. No mater how critical the process is,using all the resources you have for a single process is a bad idea.
mbalparda
CC BY-SA 3.0
2014-07-05T15:31:42.393Z
Of course, as with most things related to programming... it all depends on your context as well. Craft itself will run in under 32M of memory on a fresh install. Start adding Assets, image transforms, complicated field layouts and templates, etc. and you'll quickly bump into that limit. If you don't want to bump up the memory limit, then your other choice is to reduce the memory consumption of your plugin.
Brad Bell
CC BY-SA 3.0
2014-07-10T18:04:42.897Z
Just added the code.
mbalparda
CC BY-SA 3.0
2014-07-04T15:54:10.917Z
2014-07-08T16:48:07.130Z
2017-04-13T12:51:00.160Z
Brad Bell
<p>If you need to make changes to each entry, then the key to avoiding memory issues is to save them one at a time (or possibly in batches), rather than trying to fetch and update all the entries at once.</p>

<p>Before you do anything, tell the TemplateCachesService to delete all template caches, so that it’s not going to try to selectively delete caches each time you re-save an entry:</p>

<pre><code>// Delete all the entry caches
craft()-&gt;templateCache-&gt;deleteCachesByElementType('Entry');
</code></pre>

<p>Next up, get all of the entry IDs that you want to edit. (See our <a href="http://buildwithcraft.com/docs/plugins/working-with-elements">Working With Elements guide</a>.)</p>

<pre><code>// Now find the entry IDs
$criteria = craft()-&gt;elements-&gt;getCriteria('Entry', array('section' =&gt; 'mySectionHandle', 'limit' =&gt; null, 'status' =&gt; null, 'localeEnabled' =&gt; null));
$criteria-&gt;section = 'mySectionHandle';
$criteria-&gt;limit = null;
$criteria-&gt;status = null;
$criteria-&gt;localeEnabled = null;

$entryIds = $criteria-&gt;ids();
$totalEntries count($entryIds);
</code></pre>

<p>And finally, loop through the IDs and fetch/save each entry individually.</p>

<pre><code>foreach ($entryIds as $entryId)
{
    $entry = craft()-&gt;entries-&gt;getEntryById($entryId);

    if (!$entry)
    {
        continue;
    }

    // Make your changes
    $entry-&gt;getContent()-&gt;myCustomField = 'foo';

    // Save it
    $success = craft()-&gt;entries-&gt;saveEntry($entry);

    if (!$success)
    {
        // Log the error in this plugin's log file (in craft/storage/runtime/logs/fooplugin.log)
        $error = 'Encountered the following validation errors when trying to save entry # "'.$entry-&gt;id.'":';

        foreach ($entry-&gt;getAllErrors() as $attributeError)
        {
            $error .= "\n - {$attributeError}";
        }

        FooPlugin::log($error, LogLevel::Error);
    }
}
</code></pre>

<p>Note that saving new content gets a little complicated if you have any relational or Matrix fields on the entry. Probably warrants another question.</p>

CC BY-SA 3.0
2014-07-10T18:46:58.260Z
This is the way to go in this case! Thank you B!
mbalparda
CC BY-SA 3.0
2014-07-10T18:19:34.763Z
2014-07-10T18:19:34.763Z
Brandon Kelly
<p>I'm trying to do a stock update for all entries within a channel with a cronjob once a day, and I can't achieve it, because I always get <em>Allowed memory size of X bytes exhausted</em> (tried to allocate Y bytes).</p>

<p>Entries are around 2000 and the server is an <a href="http://en.wikipedia.org/wiki/Amazon_Elastic_Compute_Cloud" rel="nofollow">EC2</a> medium instance. The cron I'm using is:</p>

<pre><code>0 9 * * * wget -O /home/ubuntu/cronStock http://domain.com/actions/garp/cron/changeStock
</code></pre>

<p>I will try to create a simpler script without all the loaders Craft calls in a controller, but I'm not sure it will work.</p>

<p>Code:</p>

<pre class="lang-php prettyprint-override"><code>public function actionChangeStock()
{
    foreach ($this-&gt;getAllFromChannel('productVariants', 10) as $key =&gt; $entry) {

        //$entry = $this-&gt;getElementByField("3081001100390", ElementType::Entry, null, "variantSku");
        //$entry-&gt;enabled = false;
        $entry-&gt;getContent()-&gt;setAttributes(array(
            'variantStock'  =&gt; $this-&gt;getStockFromGarp($entry-&gt;variantSku)
        ));
        $success = craft()-&gt;entries-&gt;saveEntry($entry);

        echo $entry-&gt;variantSku.': '.$entry-&gt;variantStock.'&lt;br&gt;';
    }
    die();
}

protected function getAllFromChannel($channel, $limit = null) {
    $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry);
    $criteria-&gt;section = $channel;
    $criteria-&gt;limit = $limit;

    return $criteria-&gt;find();
}
</code></pre>

<p>How can I fix this problem?</p>

CC BY-SA 3.0
2014-07-08T17:49:02.773Z
I would recommend swapping out the example code you have provided... The cron job itself is not really useful information, it's the **PHP code** which will reveal exactly what is happening.
Lindsey D
CC BY-SA 3.0
2014-07-10T18:04:01.493Z
Done, code added.
mbalparda
<plugin-development>
Memory issue when updating all entries from a channel (allowed memory size of X bytes exhausted (tried to allocate Y bytes))
# Memory issue when updating all entries from a channel (allowed memory size of X bytes exhausted (tried to allocate Y bytes))

(Asked by: username_0 on 2014-07-04)

I'm trying to do a stock update for all entries within a channel with a cronjob once a day, and I can't achieve it, because I always get Allowed memory size of X bytes exhausted (tried to allocate Y bytes).
Entries are around 2000 and the server is an EC2 medium instance. The cron I'm using is:
0 9 * * * wget -O /home/ubuntu/cronStock http://domain.com/actions/garp/cron/changeStock

I will try to create a simpler script without all the loaders Craft calls in a controller, but I'm not sure it will work.
Code:
public function actionChangeStock()
{
    foreach ($this->getAllFromChannel('productVariants', 10) as $key => $entry) {

        //$entry = $this->getElementByField("3081001100390", ElementType::Entry, null, "variantSku");
        //$entry->enabled = false;
        $entry->getContent()->setAttributes(array(
            'variantStock'  => $this->getStockFromGarp($entry->variantSku)
        ));
        $success = craft()->entries->saveEntry($entry);

        echo $entry->variantSku.': '.$entry->variantStock.'';
    }
    die();
}

protected function getAllFromChannel($channel, $limit = null) {
    $criteria = craft()->elements->getCriteria(ElementType::Entry);
    $criteria->section = $channel;
    $criteria->limit = $limit;

    return $criteria->find();
}

How can I fix this problem?

**Tags:** plugin-development
> **Comments:**
> **username_1**: I would recommend swapping out the example code you have provided... The cron job itself is not really useful information, it's the **PHP code** which will reveal exactly what is happening.  
> **username_0**: Done, code added.  

---

## 4 answers

### Answer by username_2 on 2014-07-10. Score: 6 | Accepted answer

If you need to make changes to each entry, then the key to avoiding memory issues is to save them one at a time (or possibly in batches), rather than trying to fetch and update all the entries at once.
Before you do anything, tell the TemplateCachesService to delete all template caches, so that it’s not going to try to selectively delete caches each time you re-save an entry:
// Delete all the entry caches
craft()->templateCache->deleteCachesByElementType('Entry');

Next up, get all of the entry IDs that you want to edit. (See our Working With Elements guide.)
// Now find the entry IDs
$criteria = craft()->elements->getCriteria('Entry', array('section' => 'mySectionHandle', 'limit' => null, 'status' => null, 'localeEnabled' => null));
$criteria->section = 'mySectionHandle';
$criteria->limit = null;
$criteria->status = null;
$criteria->localeEnabled = null;

$entryIds = $criteria->ids();
$totalEntries count($entryIds);

And finally, loop through the IDs and fetch/save each entry individually.
foreach ($entryIds as $entryId)
{
    $entry = craft()->entries->getEntryById($entryId);

    if (!$entry)
    {
        continue;
    }

    // Make your changes
    $entry->getContent()->myCustomField = 'foo';

    // Save it
    $success = craft()->entries->saveEntry($entry);

    if (!$success)
    {
        // Log the error in this plugin's log file (in craft/storage/runtime/logs/fooplugin.log)
        $error = 'Encountered the following validation errors when trying to save entry # "'.$entry->id.'":';

        foreach ($entry->getAllErrors() as $attributeError)
        {
            $error .= "\n - {$attributeError}";
        }

        FooPlugin::log($error, LogLevel::Error);
    }
}

Note that saving new content gets a little complicated if you have any relational or Matrix fields on the entry. Probably warrants another question.

> **Comments:**
> **username_0**: This is the way to go in this case! Thank you B!  

---

### Answer by username_2 on 2014-07-08. Score: 10

If you just want to re-save a large number of entries without modifying them, you can run a ResaveElements task, which takes some basic parameters and re-saves all the entries that match them.
You can do that like this:
// Queue up a new ResaveElements task
craft()->tasks->createTask('ResaveElements', null, array(
    'elementType' => ElementType::Entry,
    'criteria'    => array('section' => 'mySectionHandle', 'limit' => null, 'status' => null, 'localeEnabled' => null)
));

// Start running tasks
craft()->tasks->runPendingTasks();

> **Comments:**
> **username_0**: I think this is the answer im looking for. I need to update the products programmatically and i need to set a field by product, a stock attribute based on a 3rd party service. Is this possible with this approach?  
> **username_2**: @mbalparda Sorry, didn’t realize you actually needed to _modify_ the entries in the process, but I suppose that should have been obvious :) I’ll post a new answer…  
> **username_3**: For anyone looking for how to do this in Craft 3 (As I was): https://docs.craftcms.com/v3/updating-plugins.html#background-tasks  

---

### Answer by username_4 on 2014-07-08. Score: 3

It's likely because PHP's per-process memory limit is set too low for this particular script. I would not raise it globally using your php.ini file, but raise it right in your script on a per-process basis, right inside of your template.

I put together a quick plugin to do this (and set other ini\_set parameters):
<https://github.com/jpeacock/setini/>

> **Comments:**
> **username_2**: Nice! You should post that on [Straight Up Craft](http://straightupcraft.com/craft-plugins) – will have a lot of other cool uses :)  
> **username_5**: Worth noting that ini_set won't work if you're using fastcgi, but will if you're using mod_php.  
> **username_4**: I just changed it up to be a bit more generic. It now lets you pass in the parameter that you want to change (in this case 'memory_limit') and the value to change that parameter to.  
> **username_1**: Nice work @jpea, I like the Twig filter approach! I built a plugin awhile back which also let's you modify ini setting, but on a larger system-wide scale: [PHP Tweak](https://github.com/lindseydiloreto/craft-phptweak). I do admire the precision of your Twig filter technique. :)  
> **username_0**: This is really good, but im having issues with a controller and not with a view. I already tried moving memory limits and it is still not working.  
> **username_4**: What type of EC2 medium instance do you have? There are a bunch of types within the "medium" realm all of which have different memory offerings. http://aws.amazon.com/ec2/instance-types/ - Also, how much are you allocating to PHP? (a quick phpinfo() will show you memory_limit).  

---

### Answer by username_5 on 2014-07-04. Score: 3

I've got no idea what your script is actually doing, but it sounds like it's pretty memory intensive and PHP is simply running out of it's allocated memory trying to finish executing the script.

Bump up the memory\_limit in your php.ini file to something larger (128M, 256M, 512M, etc.) and try the script again. Note that you may or may not have to restart your web server before the setting takes affect.

Another option, is to use Craft's `TasksService`, which runs these memory intensive, long running tasks in the background in small batches to avoid memory limitations like this.

If you're simply resaving all of the entries in the system, you can also look at triggering Craft's `ResaveElements` task, like [Brandon pointed out](https://craftcms.stackexchange.com/a/823/57). If your plugin needs to do some custom logic outside of the scope of `ResaveElements`, it can create it's own task to register with Craft and run. We don't have any documentation for that up, yet, but if you look at `craft/app/tasks` and `craft/app/services/TasksService.php` you can get a good idea of what's required.

> **Comments:**
> **username_0**: When i was starting to code i had this issue and this answer popped everywhere. After 5 years of coding large systems, i realize this was not a good idea. Basically you are killing your own server for a single process. No mater how critical the process is,using all the resources you have for a single process is a bad idea.  
> **username_5**: Of course, as with most things related to programming... it all depends on your context as well. Craft itself will run in under 32M of memory on a fresh install. Start adding Assets, image transforms, complicated field layouts and templates, etc. and you'll quickly bump into that limit. If you don't want to bump up the memory limit, then your other choice is to reduce the memory consumption of your plugin.  
> **username_0**: Just added the code.  

---

