May 6, 2010 5
Why Rails asset caching is broken in your app and how you can fix it

Ruby on Rails’ helper methods (image_tag etc.) that generate URLs to assets (assets are static resources like stylesheet, image, and javascript files) use the broken caching strategy of timestamped query strings, which fails to provide desirable caching behaviour. The new Asset Fingerprint plugin fixes this problem by making it easy to use a file name fingerprint solution (recommended by Google) to improve the cacheability of your app.
Why using the query string is a bad idea
From Google’s advice on leveraging proxy caching:
Most proxies, most notably Squid up through version 3.0, do not cache resources with a “?” in their URL even if a Cache-control: public header is present in the response. To enable proxy caching for these resources, remove query strings from references to static resources, and instead encode the parameters into the file names themselves.
Google uses the term “fingerprinting” to describe putting parameters in a file name to identify a unique version of that file.
Why using file timestamps is a bad idea
File timestamps are not recommended as resource fingerprints as these are often inconsistent between deployments when a file has not changed. This means your app may not take full advantage of asset caching. Reasons for timestamp inconsistency include:
- multiple app servers checking out files from code repo at different times
- git does not preserve file timestamps (it really doesn’t)
- subversion not configured to preserve file timestamps
- generated asset files (e.g. compressed css/js bundles)
A hash function checksum (e.g. MD5 checksum) of an asset file’s contents can be used to give a more reliable file fingerprint.
What the Asset Fingerprint plugin does out-of-the-box
Easiest to illustrate what the plugin does by example: say there’s an image in your app located at public/images/logo.png, the Asset Fingerprint plugin will modify Rails’ helper methods to generate asset file paths like ‘/images/logo-fp-1749689fc4ba35c5bb1a4d1a8ef903e3.png’.
The ‘-fp-’ part of the path is a fixed string used to help identify fingerprinted paths and the ’1749689fc4ba35c5bb1a4d1a8ef903e3′ part is the fingerprint of the logo.png file, which is the MD5 checksum of the logo.png file. The fingerprints are calculated once and cached for performance (like Rails does already with the file timestamps).
By default, the plugin will create symlinks on-the-fly to ensure the fingerprinted asset paths are valid and serve the expected resource. You can configure this behaviour to have symlinks generated by a rake task instead (normally run during deployment) or you can use server rewrite rules if you prefer – the plugin’s README explains this and provides examples.
What else the Asset Fingerprint plugin can do
You can configure the plugin in a single line to use timestamps as fingerprints if you prefer, or you could write a SHA-2 FingerPrinter if you have a problem with MD5.
If you have an urge to put the fingerprint in the query string (as Rails does by default) that is a single line of configuration.
Who uses the plugin?
At time of writing Asset Fingerprint is used in production for MissedConnections.com.
How to get the plugin?
You can find source and in-depth details of the Asset Fingerprint plugin, including installation and customization instructions on Github.
TLTR summary Rails’ timestamped query string asset caching is broken. Install the Asset Fingerprint plugin in your app to fix it and improve the cacheability of your app.




