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?
- Uploading the file to temporary storage via an aws put.
- Making an aws head request to check that the file exists.
- Downloading the file to disk via an aws get.
- Uploading the file to the permanent storage via an aws put.
- 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