Ruby on Rails: Avoiding Cache Stampedes with race_condition_ttl

Gonzalo Galdámez
Unagi
Published in
2 min read5 days ago
Ruby on Rails: Avoiding Cache Stampedes with race_condition_ttl

Today we’re discussing Cache Stampedes in Ruby on Rails and how to prevent them using :race_condition_ttl.

What is a Cache Stampede?

Imagine we have many applications (or threads) that need the same information from our database. We store that information in the cache to avoid overloading the DB with queries and save time.

Now, what happens when the cache entry expires? If many applications try to fetch that information simultaneously, they might all attempt to update the cache simultaneously upon realizing it has expired. This is known as a Cache Stampede, and it can significantly overload our server.

Preventing Cache Stampedes in Ruby on Rails with :race_condition_ttl

Rails includes the :race_condition_ttl option to help avoid this issue. The idea is simple: when a cache entry expires, only one application is allowed to update it, while others wait a bit before trying again.

Example of how to use :race_condition_ttl in Rails

Suppose we want to cache the results of a heavy database query.

Rails.cache.fetch("heavy_db_query", expires_in: 5.minutes, race_condition_ttl: 10.seconds) do
# This next line makes a heavy query to the database
HeavyModel.expensive_query
end

In the example above:

  • heavy_db_query: is the key name we use to save our query in the cache.
  • expires_in: 5.minutes: sets the cache to expire in 10 minutes.
  • race_condition_ttl: 10.seconds: ensures that if multiple requests hit an expired cache, only one will update it while the others wait up to 10 seconds before trying again.

Conclusion

Saw how easy that was? By using :race_condition_ttl, Ruby on Rails provides a simple and efficient way to prevent Cache Stampedes and reduce the load on our servers.

Unagi provides software development services in #Ruby and #JavaScript, a stack we still choose after 12+ years. Check out more about us.

--

--