Member-only story
Harnessing Client-Side Caching in Rails: The Power of `expires_in`
In your journey as a software developer, you’ll encounter myriad tools and techniques designed to optimize and streamline web applications. One such tool, often overlooked, is client-side caching. As backend and full-stack engineers, we spend hours crafting complex caching layers on the backend. However, we often overlook the most effective caching technique: having the request never reach the backend! Let’s delve into how requests get cached on the client using the Cache-Control
header.
Cache Control Header
At the core of client-side caching is the HTTP Cache-Control
header. This header offers directives to browsers (and other caching agents) about how they should cache the content and when to consider it stale.
The most common directives include:
- max-age: Specifies the number of seconds the response remains fresh.
- no-cache: Directs caching agents to revalidate with the server before using the cached version.
- public/private:
public
means that any cache, including CDNs, can store the response.private
ensures the response is user-specific and only cached at the end-user level.
By setting the appropriate cache control headers, developers can steer the caching behavior of browsers and intermediaries, thereby optimizing both server load and user experience.
Rails expires_in
in Controller Actions
In the Rails ecosystem, the expires_in
method is our key to effortlessly managing the cache control header. Within the context of Rails actions, using expires_in
sets the Cache-Control
header on the HTTP response.
Take, for instance, an application like Designer Discount Club I’m currently building. The product data updates roughly once a day, and constructing the response requires complex queries and interactions with multiple services. Below, the display_cards
action powers an infinite scroll list on the client. By implementing expires_in 1.hour, public: true
, we essentially direct clients to retain and reuse their cached response for an hour. When users navigate back and forth, adding this cache control header reduces ~100ms round trip time from the client's perspective and diminishes request volume to our backend Redis cache by over 60%.