Make Vips the recommended/default variant processor for Active Storage

Currently, the ActiveStorage guide opening section contains the following phrase: “Using Active Storage, an application can transform image uploads with ImageMagick”.

A developer looking to start using ActiveStorage will assume that this is Rails recommendation, even if they later see in the Transforming Images section that using vips is possible.

It is my experience, running Active Storage in production since version 5.2, that this is not a good enough default and Rails should steer users away from it, and incentivize them to use vips instead.

The original PR by janko gave the technical reasons why supporting vips was a good idea, so I’ll stick to explaining why vips is better from a user experience point of view.

Vips is faster, so it improves queue times

Let’s say you have a feature in your app that allows your user to upload multiple photos at the same time, and after the upload is done you direct them to their photo gallery. Let’s also say that your user just uploaded 5 photos.

When that user reaches the photo gallery, his browser will make 5 requests to the representations_controller, which will start processing the 5 variants, keeping 5 puma workers occupied. For smaller apps, that might be as many workers as they have available, which means that every other HTTP request must wait until the representations_controller is done processing the variant. This wait time is the “queue time”. With its faster processing vips can reduce the queue time and provide a faster user experience.

This is specially bad on Heroku. From my experience in the CGRP Slack group and from talking to other devs, I’ve noticed that many are using Heroku as a host and using Standard-1x or Standard-2x dynos with a puma concurrency of 1-2. Since Heroku’s load balancer assigns requests at random, this means that even if there are puma workers free, users nagivigation requests might get stuck in the queue of a server that is busy processing an image.

Back when we were in Heroku this got so bad that we could tell when a user had uploaded a large amount of photos at the same time by the fact that there was a spike in queue times and the auto scaler had kicked in.

Vips consumes less memory, so it improves response times

ImageMagick is very memory intensive when processing variants. Benchmarks by libvips author demonstrate it using 3GB memory versus 200MB by vips. With cameras in mobile phones getting better and better, the photos that must be processed are becoming larger. This inefficiency causes problems for developers running their apps in servers with tight memory constraints, like 512MB or 1GB (eg: Heroku). With Rails apps already being memory intensive, they should be always close to the memory ceiling.

Processing a single photo with ImageMagick might be enough to force the server to start swapping, and this kills ActiveRecord’s performance. I’ve seen Scout reporting that a simple find had increased from 1-2ms to 10-30ms sometimes as much as 50ms when our Heroku dyno reached its memory limit. With most pages requiring a few queries, we are talking about an additional few hundred ms of response time for at least as long as ImageMagick is processing.

Conclusion

Recommending Vips is a form of conceptual compression. It eliminates the need for developers to understand how Active Storage’s chosen implementation for variant generation, when combined with ImageMagick slow processing and high memory requirements, is impacting their user’s experience.

Vips creates a better user experience. Let’s make it the recommended option. If possible, let’s make it the default in Rails 7 since it’s a major version and allowed to introduce breaking changes.

The PR: Make vips the default variant processor by brenogazzola · Pull Request #42744 · rails/rails · GitHub

6 Likes

I’ve prepared a gist with a step by step guide on how to make the migration, based on my experience doing that:

3 Likes

I agree about making vips the default image processor and I think there is another argument to be made: security. We are not running ActiveStorage due to the high security we need for our storage. Running transformations on uploaded files is often a security risk as the tools have lots of vulnerabilities. Most developers seem to run the transformation binaries on the same webserver as the rest of their application, making it even more insecure.

The list of known CVE’s in vips is significantly smaller than the list of known CVE’s for ImageMagick. I’m not familiar with the internals of both tools, so vips’ lower number of CVE’s can mean a better security architecture or less CVE’s found due to being a less popular tool. For me it seems to be a more secure option if you don’t take other security measures for transformations.

3 Likes

Thx for sharing with us!

1 Like

I’m happy to say this one has been merged :heart_eyes:

1 Like