Question
How can I prevent out of memory (OOM) errors for a Rails app using ImageMagick to resize uploaded images?
I have a Ruby on Rails application hosted on Heroku. The Rails app uses ActiveStorage and ImageMagick to resize the images uploaded by users.
Sometimes uploaded images are too large and there are OOM errors causing the server to crash.
Answer
The first solution is to add a validation on the size of the files uploaded by users. This can be considered a best practice and should be always applied.
For example:
# Gemfile
gem 'active_storage_validations'
# Model
validates :image, content_type: 'image/jpeg', size: { less_than: 30.megabytes }
30MB is a size used by many popular social networks and allows the upload of high resolution images, including those taken with professional cameras (e.g. 60MP).
In addition to that you can control how much memory can be allocated by ImageMagick for processing the image (e.g. resize) using some environment variables:
MAGICK_MEMORY_LIMIT=512MiB
MAGICK_MAP_LIMIT=1GiB
MAGICK_DISK_LIMIT=2GiB
ImageMagick will first try to use memory (fast), then a memory-mapped file and finally the disk (slow). If the disk limit is still not enough for the pixel cache, the command fails with an error.
After setting the ENV variables, you can use the following command to verify the current settings:
identify -list resource