Caching Rendered PDFs in Rails with Active Storage
Contents
As I was working on easyclientlog.com, building its invoice system that allows freelancers/consultants to generates PDFs. Working with PDF generating is that, its takes time and CPU cycles. But most of the time the pdf only needs to be generated once, and the content seldom changes. So rendering the same thing over and over just didn’t feel right. So I used a simple trick that I’ve followed in many of my prior Rails apps: upload the PDF on first render, store it using Active Storage, and reuse that file on the next access.
The Idea: Cache on First Render
When the PDF is generated the first time, we attach it to the record using Active Storage. This could be an invoice, report, or any other object. The next time we need to show or download the PDF, we skip the rendering step and simply serve the uploaded file.
This avoids unnecessary rendering and speeds up response times, especially for large documents or when generating in bulk.
How It Works
Let’s say we have an Invoice model. We attach the PDF like this:
|
|
Now in the PDF rendering service, we check if the file already exists. If yes, we use it. If not, we generate the PDF and attach it.
|
|
When to Invalidate the Cache
In our case, the cache/storage is cleared by deleting the attached PDF when the invoice is updated:
|
|
This deletes the old file. Active Storage will take care of removing it from the cloud (S3, GCS, etc.) in the background.
Alternatively, you could skip deletion and just change the filename by including updated_at. This way, older versions are not used, and Active Storage can expire old files on its own using lifecycle rules.
Summary
Instead of rendering the same PDF again and again, use Active Storage to cache it. Attach the file on first render and reuse it. Delete it when updating the record, or use the updated_at time in the filename and compare on file download if
the pdf has changed.
This trick has helped me improve performance and simplify my code in apps where PDFs are generated regularly. Hope it helps you too.
Note: If you are adding some dynamic data to your PDF like download time, then this method can’t be used.