Rails file download via send_file is slow, is X-Sendfile or similar available in puma?

Viewed 1464

Downloading off the public folder takes 2 seconds.
Downloading the same file using the send_file method below takes nearly a minute.

  def download
    file = FileUpload.find params[:id]
    file_path = Rails.root.join('private', file.name)
    send_file(file_path,
              x_sendfile: true, 
              disposition: 'attachment')
  end

I have tried changing buffer size and so on but it's still extremely slow, slower than the database & send_data combination.
Apart from ditching Rails entirely, is there an simple solution to this?

2 Answers

When using Heroku or similar services, sometimes it isn't possible (or convenient) to configure nginx.

In these cases it makes sense to use an application server that supports X-Sendfile, such as iodine or agoo.

My biased suggestion is to use the iodine server with it's static file service option in the procfile, for example:

iodine -w 4 -t 16 -www ./public

Since assets are compiled to ./public/assets*, than the static file requests will be directly handled by iodine without ever entering the Ruby application (the C server layer will handle them).

* RAILS_ENV=production bin/rails assets:precompile compiles assets to ./public/assets

Related