Simple Change To Boost Carrierwave Performance

The Problem

If you use fog or aws as your carrierwave storage mechanism, by default it spends a bunch of time moving the uploaded file between
temporary storage (cache) and permanent storage (store)

config.storage = :aws
# OR
config.storage = :fog

How Is Carrierwave Spending This Time?

  1. Uploading the file to temporary storage via an aws put.
  2. Making an aws head request to check that the file exists.
  3. Downloading the file to disk via an aws get.
  4. Uploading the file to the permanent storage via an aws put.
  5. Deleting the temporary file via an aws delete.

This means for each file upload it performs at least 5 network requests to aws, 3 of which include the entire contents of the uploaded file. This file movement takes a lot of time and wastes money on unneeded network traffic.

The Solution

If you take a closer look at the carrierwave README you will come across this commented configuration option:

  # For an application which utilizes multiple servers but does not need caches persisted across requests,
  # uncomment the line :file instead of the default :storage.  Otherwise, it will use AWS as the temp cache store.
  # config.cache_storage = :file 

So if you do not need to persist cached files between servers (primarily used for returning form errors without requiring users to re-upload files) and you enable this option it will cut out steps 1,2,3, and 5 from the default flow. The loss of these 4 network heavy steps has a tremendous impact on overall performance and network usage costs.

Results

In our particular use cases we have seen response times that include files in the body speed up across the board. Some of them by more than a second. Hard to judge the positive monetary impact but theoretically it is there. I hope this small change has the same effect on your application and organization.

  config.storage = :aws 
  config.cache_storage = :file # stop putting tmp files in s3 causing an upload/download/upload/delete chain