April 2, 2024
Image processing servers benchmark
Delivering images to users as fast as possible is crucial for any web application. In the pre-processing era, we didn't care much about the image processing speed since all the images were processed when they were uploaded. But now, with the rise of on-the-fly image processing, picking the fastest server is critical. In this article, we will compare the performance of the most popular image processing servers.
We picked the three most popular image processing servers for this benchmark:
- imgproxy: An image processing server written in Go with libvips under the hood. The main principles of imgproxy are simplicity, speed, and security.
- thumbor: A veteran in the on-the-fly image processing world. It's written in Python and uses Pillow for image processing.
- imagor: An alternative to thumbor with thumbor-compatible API. Just like imgproxy, it's written in Go and uses libvips for image processing.
But where's %MY_FAVORITE_TOOL%?
In our previous benchmark that we ran in 2019, we included more tools like imaginary, Pillbox, and some pure Go servers. However, at the moment of writing this article, imaginary seems to be abandoned, and Pillbox is marked as deprecated. We also excluded pure Go servers since they show very poor performance.
Benchmark environment
We ran all the tests on the following AWS EC2 instances:
- c7i.large: 2 vCPUs (x86_64, Intel Xeon Platinum 8488C), 4GB RAM (DDR5)
- c7g.large: 2 vCPUs (arm64, AWS Graviton3), 4GB RAM (DDR5)
All the tools were running in Docker containers. For imgproxy and imagor, we used the latest versions of the official Docker images. Thumbor lacks an official Docker image, so we built a Docker image with the latest version of thumbor.
Caching was disabled for all the tools to measure the pure image processing speed.
The test images were taken from the DIV2K dataset and converted to JPEG, PNG, WebP, and AVIF formats. The images were served with a local Nginx server to mitigate any network speed fluctuations.
We used k6 to simulate the load and measure the latency. We ran each test with 2 virtual users (by the number of CPU cores) for 5 minutes.
The test case was to resize an image to fit into a 512x512 square and save it to the original format with the provided quality (when applicable).
We published the benchmark code on GitHub so you can run it yourself.
Now, let's go to the results!
JPEG
For JPEG resizing tests, imgproxy and thumbor were configured to save images as progressive JPEGs. Imagor saves JPEGs as progressive by default. The resulting quality was set to 80
for all the tools.
Tool | CPU | Requests per second |
---|---|---|
imgproxy | Intel Xeon Platinum | 79.623415 |
AWS Graviton3 | 81.956301 (+3%) | |
thumbor | Intel Xeon Platinum | 51.644103 (-35%) |
AWS Graviton3 | 63.383205 (-20%) | |
imagor | Intel Xeon Platinum | 21.323007 (-73%) |
AWS Graviton3 | 35.66299 (-55%) |
In the JPEG resizing tests, imgproxy was the fastest tool for both Intel Xeon and AWS Graviton3 CPUs. imgproxy didn't gain much from running on Graviton3-powered instances, but thumbor and imagor showed a significant performance improvement compared to the Intel Xeon Platinum instances. However, considering the lower cost of Graviton3 instances, even a small performance improvement is a good reason to switch to Graviton3.
PNG
There are not many things to configure for PNG resizing tests. All the tools use the same default compression level for PNGs and don't use interlaced PNG encoding, so we kept all the PNG-related settings as default.
Tool | CPU | Requests per second |
---|---|---|
imgproxy | Intel Xeon Platinum | 19.246237 |
AWS Graviton3 | 22.297412 (+16%) | |
thumbor | Intel Xeon Platinum | 8.878169 (-54%) |
AWS Graviton3 | 12.307963 (-36%) | |
imagor | Intel Xeon Platinum | 9.239028 (-52%) |
AWS Graviton3 | 13.502603 (-30%) |
imgproxy showed the best performance for PNG resizing tests as well. On Intel Xeon Platinum-powered instances, imgproxy showed more than twice as much performance than thumbor and imagor. All the tools showed a significant performance improvement on Graviton3-powered instances, but the performance gap between imgproxy and the other tools was still significant.
WebP
For WebP resizing tests, the resulting quality was set to 75
for all the tools. The rest of the WebP-related settings were kept as default.
Tool | CPU | Requests per second |
---|---|---|
imgproxy | Intel Xeon Platinum | 22.0398 |
AWS Graviton3 | 26.243328 (+19%) | |
thumbor | Intel Xeon Platinum | 13.17094 (-40%) |
AWS Graviton3 | 16.444144 (-25%) | |
imagor | Intel Xeon Platinum | 12.017389 (-45%) |
AWS Graviton3 | 16.699987 (-24%) |
No surprises here: imgproxy was the fastest tool for WebP resizing tests as well. The performance improvement on Graviton3-powered instances was significant for all the tools, but imgproxy still showed the best performance.
AVIF
For AVIF resizing tests, the resulting quality was set to 65
for all the tools. AVIF encoding speed was set to maximum for imgproxy and thumbor. Unfortunately, imagor doesn't have the option to set the AVIF encoding speed. This makes this test unfair for imagor, but we can't do anything with it, so we included it just for the sake of completeness.
Tool | CPU | Requests per second |
---|---|---|
imgproxy | Intel Xeon Platinum | 13.234077 |
AWS Graviton3 | 17.785054 (+34%) | |
thumbor | Intel Xeon Platinum | 13.065488 (-1%) |
AWS Graviton3 | 13.759703 (+4%) | |
imagor | Intel Xeon Platinum | 1.612713 (-88%) |
AWS Graviton3 | 2.141814 (-84%) |
What a race we have here! imgproxy and thumbor showed almost the same performance on Intel Xeon Platinum-powered instances, the gap between them may even look like a measurement error. However, things changed on Graviton3-powered instances: thumbor showed a slight performance improvement, while imgproxy overtook it confidently with a huge performance boost.
As for imagor, there were no surprises: the lack of AVIF encoding speed setting made it the slowest tool for AVIF resizing tests.
Conclusion
For the five years that have passed since our previous benchmark, the balance of power didn't change much. Though thumbor improved its performance, and we saw a new player, imagor, imgproxy is still the fastest racer on the on-the-fly image processing track.
We also wanted to test the image processing performance on AWS Graviton3, and we were very impressed: the performance boost in some tests was quite significant. Yet we weren't surprised: we have been AWS Graviton fans for years and always recommended running imgproxy on Graviton-powered instances.