Resolving “Stalled” Background Tasks

General Debugging Tips: #

If Craft does not see any activity from a task after five minutes, the task will be marked as “Stalled” in the Control Panel. You will then have the option to “Try again”, which will restart the task or “Cancel”, which will cancel the task and delete it from the database.

Note that in the rare case that a task is actually still running after five minutes without providing any status update to Craft, the task will still be marked as “Stalled” in the Control Panel. As soon as the task provides the next status update, the Control Panel will show that it is back in a running state again.

If the task continues to stall after re-trying, you are likely running into some environmental limitation including (but not limited to):

There’s a good chance something is getting logged in craft/storage/runtime/logs/phperrors.log. Check that file and see if there are any recent logs in it. If it was a fatal error coming from your web server (Apache/nginx/etc.), check their error log files as well.

Debugging stuck “Delete Stale Template Caches” tasks #

The “Delete Stale Template Caches” task is created when you use the native Craft template {% cache %} tag and one of the elements inside of that tag changes. It’s worth familiarizing yourself with how the native cache tag works. There is some great discussion of its internals here and here.

If it gets stuck, in addition to the general debugging tips above, here are some more specific steps for this task.

  • Find and fix the underlying issue that’s causing the task to become stuck. A task is a PHP request just like any other request and is subject to the same environmental limitations as PHP is. By their nature, if you’re caching a lot of data, then they will take longer to run and consume more memory increasing their chances of a failure.

If that isn’t an option to you (for whatever reason), you can:

  • Don't use the native {% cache %} tag. Use Varnish or some other front-end caching solution instead.

  • Use the {% cache %} tag, but set the cacheElementQueries config setting to false, and come up with your own strategy for deciding when to delete template caches. i.e. a cron job, or every 30 minutes on Tuesdays, etc.

  • Use a caching plugin that has different caching behavior than the native {% cache %} tag implementation, such as ColdCache or CacheFlag.

  • It’s probable you’re using the {% cache %} tag as a solution to the N+1 database problem. Use eager loading (introduced in Craft 2.6) instead of caching.

Some general rule-of-thumb things to know to reduce the chances of this task failing:

  • Craft has to keep track of every single element (Asset, User, Matrix Block, Entry, etc.) inside of a {% cache %} tag to to know when to intelligently bust the cache if one of those elements has changed. Each one of those elements basically ends up being another step in the “Delete Stale Template Caches” task. Smaller, more focussed cache tags that just focus on database heavy parts of the template are much better than, for example, putting a {% cache %} tag in your base layout template and just caching everything.

  • Be explicit with your cache keys. By default Craft will use the current page URI as the cache key (including the query string), which may or may not be the best behavior for your site. If you are getting pages hammered with tons of query string variations, then that creates extra (probably unnecessary) caches that the task also has to account for.

If, after taking all of this information into account, you’re unsure how to resolve it, you can either either create a new ticket from your Dashboard or email us with a zip of your entire craft/storage/runtime/logs/ folder, and we’ll help you get through this.

Debugging stuck “Generate Pending Transforms” tasks #

The “Generate Pending Transforms” task is created when you’ve got a template that references an image transform and that transform has not been generated yet.

This task is particularly sensitive the memory limitations and execution time limits listed in the General Debugging Tips section because processing images in PHP is, by nature, a memory intensive operation.

So be sure your template is not trying to transform twenty 4,000 x 2,000 resolution images in a template on a shared host where PHP is limited to 64MB of memory.

At a 4,000 x 2,000 resolution, a single 32-bit CMYK PNG file requires nearly 31MB of memory just to load the image into memory, much less perform an transform on it and that is not taking into account the memory overhead that Craft/PHP needs to operate.

It is also important to know what the underlying image processing library your server has installed to process these images.

Craft supports both GD and Imagick, but we recommomend the latter because it supports and wider range of image formats, generally produces better quality output and has more image manipulation options avaiable. By default, Craft will automatically use it if it sees it is available. You can explicitly force Craft to use one or the other with the imageDriver config setting.

Aside from the normal memory and execution time limits, it’s common for the “Generate Pending Transforms” task to get stuck if you are using GD and trying to transform an image that GD doesn’t support, like a 32-bit PNG.

It is also fairly common that you are running into a bug in either GD or Imagick from running an older version of the libraries. In general, we recommend running the latest stable version of the respective library as possible.

The GD release version history can be found here: https://github.com/libgd/libgd/releases

The Imagick release version history can be found here: https://www.imagemagick.org/script/changelog.php and the related PHP Imagick wrapper here: https://pecl.php.net/package/imagick