github << rails / stimulus / hotwire

Rails: Stream File Downloads (PDF/CSV) October 09, 2025

Something I learned in the past while building several export pages was to “stream” file downloads (e.g. pdf, csv), especially if the size is huge or dynamically depends on record associations. You wouldn’t want to do a full file download because it is likely that there will be timeout and memory problems.

In this case, it’s a two-step process: (1) setting the response headers, and (2) building the file contents through an Enumerator.

class CsvDownloadController < ApplicationController
def index
respond_to do |format|
format.csv do
# Step 1: Setting the response headers
headers["X-Accel-Buffering"] = "no"
headers["Cache-Control"] = "no-cache"
headers["Content-Type"] = "text/csv; charset=utf-8"
headers["Content-Disposition"] = %(attachment; filename="test-sample.csv")
headers["Last-Modified"] = Time.zone.now.ctime.to_s
# Step 2: Using an Enumerator to build file contents
self.response_body = build_csv_enumerator
end
end
end
private
def build_csv_enumerator
Enumerator.new do |yielder|
yielder << ["ID", "Name", "Account Number"]
Account.find_each do |account|
yielder << [account.id, account.name, account.acc_number]
end
end
end
end