Benito Serna Tips and tools for Ruby on Rails developers

When do you need a counter cache in rails?

Maybe you have heard about the counter cache feature.

It makes finding the number of belonging objects more efficient, by keeping a column with the count.

But… When should you use it? Do you need to have a counter cache for every association count in your app?

Here are three situations when you could need a counter cache.

When you have slow counts in your views

Even if you do the count via SQL, a single count can be slow enough to need a counter cache.

Imagine you need to put the number of likes in a post.

If a post could have thousands or millions of likes, a single count, can really hit the performance of the app.

posts = Post.find(id)

# If there are thousands or millions of likes
# counting via SQL could also be slow
puts "Post likes: #{posts.likes.size}"

In this case you could try a counter cache or maybe fragment caching.

When preloading the counts in a list is slow

Sometimes preloading counts for a list via SQL is not fast enough.

Imagine you need to put the number of likes for each post in a list.

If there could be posts with thousands or millions of likes, the count for a list of posts could be really slow.

Even if you are already just preloading the counts to avoid n+1 queries with something like this:

posts = Post.limit(5)

# If there are thousands or millions of likes per post
# preloading the counts could also be slow
likes = Like.where(post_id: posts).group(:post_id).count

posts.each do |post|
  puts "Post: #{post.id}, likes: #{likes[post.id] || 0}"
end

In this case you could also try a counter cache or maybe fragment caching.

When you use a lot a count in the application

Sometimes you will be using the count in a lot of places in the app.

You will need to preload the count in every place, raising the possibility to introduce n+1 queries.

In this situation it could be a good option to implement a counter cache, even if you already have a preload object.

Related articles

Do you want to solve n+1 queries with confidence?

Sign up to download free ebook, where I will show the basics on how to deal with n+1 problems.

  • Understand the methods (joins, includes, etc...) to work with associations.
  • Identify when active record will execute a query.
  • And the tools that can help you detect n+1 queries (like the bullet gem).