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.