Daniel López Azaña

Theme

Social Media

Blog

GNU/Linux, Open Source, Cloud Computing, DevOps and more...

High CPU load when converting images with ImageMagick

Imagemagick-logo

In certain versions of ImageMagick there is a problem (probably due to a bug) when trying to convert or manipulate an image either from the command line (convert command) or through one of the many API’s available (for example PHP). The CPU usage suddenly grows beyond 100% (because this problem occurs on multiprocessor systems) and the system becomes extremely slow. Apart from thishigh CPU load , the conversion process also gets blocked, never reaching to the end. This occurs even with small images of few kilobytes.

After some research, I indeed concluded that it’s a bug present in certain versions of ImageMagick compiled with the –enable-openmp parameter running on machines with multiple processors or multiple cores.

So the first thing to do to know if the solution proposed in this post is valid for us, is to check if the system has multiple processors or multiple cores: How to know how many cores and processors has a Linux box.

Then check if your version of ImageMagick is enabled with OpenMP feature:

~# convert --version
Version: ImageMagick 6.5.7-8 2010-12-02 Q16 https://www.imagemagick.org
Copyright: Copyright (C) 1999-2009 ImageMagick Studio LLC
Features: OpenMP

If the above command displays the «Features: OpenMP» line, then everything fits and our problem of excessive CPU load can be fixed in three ways:

  1. Upgrading to a new version of ImageMagick or an earlier one stable enough that there is no bug causing this problem.
  2. Recompiling ImageMagick with the –disable-openmp parameter to not use the multiprocessor feature.
  3. Forcing ImageMagick to use only one of the available cores present in the system to perform the conversion.

The latter is perhaps the best solution to our problem because probably we will have already tried to update ImageMagick to another version, and in many cases we will have ImageMagick installed as a package from one of the Linux distributions available. Thus, compiling ImageMagick again it not a viable choice.

Note that the procedure shown below does not really solve the problem. It’s only a workaround , a «trick» allowing us to use ImageMagick without falling into the CPU freezing mentioned earlier in this article.

Limit the number of cores using MAGICK_THREAD_LIMIT

The way to force ImageMagick to use a single processor or core when performing an image conversion is using the environment variable MAGICK_THREAD_LIMIT. This variable should be set to 1 and be available in the runtime environment of the convert command. So edit the /etc/environment file and add the line MAGICK_THREAD_LIMIT=1 as shown below:

~# cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
LANG="es_ES.UTF-8"
LANGUAGE="es_ES.UTF-8"
MAGICK_THREAD_LIMIT=1

Then open a new command shell, since the current one will not load such environment variable until we log into the system again.

Setting the MAGICK_THREAD_LIMIT variable in PHP

If rather than using ImageMagick from the command line we do through libraries available for different programming languages like PHP , the above solution will not work, so we’ll have to add the MAGICK_THREAD_LIMIT=1 variable to the PHP interpreter runtime environment in order to PHP properly load it when calling ImageMagick functions.

I’m always referring to the case of using the ImageMagick native functions in our PHP code, like «$im = new Imagick(‘file.png’);» or «$im- >readImageBlob($svgin);». If conversion is performed using the system command as in «system(‘convert -resize 800×600 file1.png file2.png’);» , we’ll be calling the convert command the same way as in the previous section, in which case that solution is of course valid.

PHP from command line

env MAGICK_THREAD_LIMIT=1 php test.php

PHP from mod_fcgid Apache module

In this case the MAGICK_THREAD_LIMIT variable would be defined in the runtime environment of /usr/bin/php5-cgi command, wich is usually called from an intermediate script set in an Apache virtualhost. This wrapper script is called FCGIWrapper , and we can find the path to it in the corresponding vhosts.conf file:

<Files ~ (\.php)>
   SetHandler fcgid-script
   FCGIWrapper /var/www/cgi-bin/cgi_wrapper/cgi_wrapper .php
   Options +ExecCGI
   allow from all
</Files>

~# cat /var/www/cgi-bin/cgi_wrapper/cgi_wrapper
#! /bin/sh
export MAGICK_THREAD_LIMIT=1
exec /usr/bin/php5-cgi
CPU ImageMagick PHP
Daniel López Azaña

About the author

Daniel López Azaña

Tech entrepreneur and cloud architect with over 20 years of experience transforming infrastructures and automating processes.

Specialist in AI/LLM integration, Rust and Python development, and AWS & GCP architecture. Restless mind, idea generator, and passionate about technological innovation and AI.

Related articles

Xorg icon

How to prevent the .xsession-errors file from growing to a huge size

The .xsession-errors file is where the X Window system logs all errors that occur within the Linux graphical environment. All desktop environments, whether Gnome, KDE, Cinnamon, XFCE, LXDE, etc., and all lighter window managers like FVWM, IceWM or Window Maker make use of the X Window system. Therefore any graphical application running on your computer can cause that error messages are written to the .xsession-errors file, reason why it can grow wildly until reaching very big sizes of tens of GB or even hundreds if your disk capacity allows it.

June 25, 2017
Ctrl+S

Unlock Linux command line after pressing Ctrl+s in Bash

Since the key combination Control+s is widely used as a shortcut to save files in GUI applications such as text editors, image editors, web browsers, etc. sometimes you are betrayed by your subconscious when you are working from the Linux command line and you use that same key combination when you are for example editing a Vim document when trying to save it. Then you notice that no key answers, the shell is locked and you can no longer do anything else in it.  Even worse, you get a cold sweat because you can’t continue editing your document and you can’t save the changes.

April 27, 2017
Wordpress multilingual site

Fixing Qtranslate slug problems

There are basically two options when creating a multi-language website based on WordPress. One involves duplicating posts and pages by creating one different post for each language, wich is the approach followed by some plugins like WPML, Polylang or xili-language. Another approach is to introduce all the translations into the same post, separated by meta-tags within the content itself.Each translation is displayed in different tabs within the HTML editor of a single post. This is the case of Qtranslate, which happens to be the simplest solution from my point of view, as it is not necessary to modify the WordPress database in order to create relationships between a post or page and their translations, as well as among other WordPress objects like categories, tags, widgets, menus, etc. Therefore Qtranslate is my favorite choice when it comes to creating a multilingual website based on WordPress.

September 16, 2014

Comments

G March 21, 2012
Amazing ... down from 20s to 1s ... Thanks!
Daniel March 22, 2012
You're welcome! I'm glad that helped you.
KWardle March 26, 2012
Thanks! This also solves the problem that the convert -average function loads all the images into memory at once. Not so good if there are a lot of images. Thanks again!
KWardle March 26, 2012
Oops this was not the intended page for my previous comment. Thanks for this though, it is useful. For the other, take a look at http://stephan.paukner.cc/syslog/archives/362-Averaging-an-image-sequence-with-ImageMagick.html.
Michael July 7, 2012
As "G" said, amazing performance improving! Use –disable-openmp! :-) M.
don bright September 10, 2012
Daniel this is brilliant!!! Thank you. I spent a huge amount of time trying to diagnose this.
Noah September 25, 2012
Not what I was looking for
Dmitry October 12, 2012
That's great solution, thank you very much man! Instead of 15 sec for creating one simple thumbnail and 20% CPU load, now it takes 0 CPU and < 0.1 sec. I'm using virtual server hosting and have PHP php-imagick. Unfortunatley, env variable not works in my case with php. But here is solution that works for me: // insert this in your php before processing images Imagick::setResourceLimit(6, 1); (found here: http://stackoverflow.com/questions/2121137/limit-number-of-threads-in-imagick-php )
Daniel October 18, 2012
Thanks for the feedback Dmitry!
Mikhail November 2, 2012
Just encountered that bug on Debian Lenny with ImageMagick 6.6.0-4. Thank you for the solution!
Sergey December 13, 2012
Thanks, dude, this solution saves my balls.
seraph February 5, 2013
I used this code to fix the problem inside php-script: Imagick::setResourceLimit(6, 1);
Sumeet Kashyap February 10, 2013
I have read at some places about using this piece of code for php: putenv("MAGICK_THREAD_LIMIT=1"); Is this correct and will produce the same results?
MarkusK April 2, 2013
Thank you, this helped me a lot!
nikita April 5, 2013
Thank you!
Leon December 3, 2013
Thank you! You helped a lot with this post. For PHP+Apache it is also possible to add the variable in /etc/apache2/envvars, so a whole web server and all vhost etc. can be "fixed" at once. Took me a while to figure out, perhaps useful for somebody else trying to solve this problem.
Morty March 6, 2014
Amazing! So simple yet so cool. Saved my project :D
Steve March 21, 2015
I tried using 'Imagick::setResourceLimit (6, 1); in my php script, but ran into an issue. The thumb is created successfully, but it outputs 'Strict Standards: Non-static method Imagick::setresourcelimit() should not be called statically in...' to the page similar to an error message. Outputting that message makes it unusable for me. Any ideas?
Clau April 6, 2015
Yes, try to call the imagick method on an instance of the class, not on the class itself: $my_imagick_object->setResourceLimit(6,1); Cheers!
Bodo August 15, 2016
Just want to let you know that on my system the ->setResourceLimit(6,1); does not help. Still takes around 250(!) seconds to convert around 4 images from PDF. Horrible.
Bodo August 15, 2016
Hello I am lost with anything here and would appreciate any help. What is the solution today (2016) with that ImageMagick problem on virtual Servers ? I am simply calling it in PHP. I do not want to change all my php scripts now. It takes around 30-60 seconds for one image to convert from PDF to JPG, with some filters an re-sizing. How do I install a new ImageMagick Version without multi-core? How do I tell PHP to use this new version? The new Version 7.x.x. does not use "convert", it uses "magick" now...so I do not know how to change that. phpInfo() shows me it is still using the old version. setResourceLimit(6,1) - did not change anything on my System. No solution. I do not understand the last part of this tutorial: "wich is usually called from an intermediate script set in an Apache virtualhost. This wrapper script is called FCGIWrapper, and we can find the path to it in the corresponding vhosts.conf " I do not have a vhost.conf I do not have a cgi-wrapper file Nothing... (I have virtual hosts, but they are in the directory sites-enabled) I am so lost with that thing! :-( It seems none of the things I do can solve the problem. Why do the people who programm ImageMagick not solve it and make a single-thread option. It is so useless at the moment. Crazy.
Daniel August 16, 2016
Maybe you installed the new version of ImageMagick command line tool, but didn't upgrade php-imagick package (sudo apt-get install php-imagick), wich is the native PHP extension to create and modify images using the ImageMagick API. Note that they both have different versions. Sorry, but MAGICK_THREAD_LIMIT=1 and setResourceLimit(6,1) are the only methods I know to force 1 thread execution. And they shouldn't be necessary in recent versions of ImageMagick, as the bug mentioned in this article is probably already solved. You can write me an email and attach the files you're trying to convert and I'll try to give you additional support, as the problem could be related to something else. Otherwise, you can try with the GD graphics library to perform the same task, maybe you're luckier.
xia May 24, 2019
i have a problem;I used ' env MAGICK_THREAD_LIMIT=1' but the cpu is still too high;

Submit comment