Skip to main content

Subscribe to GoRails to get access to this episode and all other pro episodes, and new awesome content every month.

Subscribe Now
Only $19/month

Unlimited access. Cancel anytime.

27 Improve Performance With Caching:

Russian Doll Caching with Rails 5

Episode 114 · April 22, 2016

Learn how to implement efficient Russian Doll Caching with Rails 5

Performance


Transcripts

Subscribe or login to view the transcript for this episode.

Discussion


Fallback

Hey Chris, thank you for this screencast! Cache toggling feature looks awesome (I just learned it from this video). One quick question, do you recommend Redis over Memcached as a cache store?

Fallback

I do usually recommend Redis most often and the reason for that is simple: You're probably already using it to run your background jobs with Sidekiq or the like, so you might as well just take advantage of that. You can run a separate Memcached instance but I don't think you're going to see a major difference unless there is a feature you specifically need from it that Redis doesn't provide. Basecamp uses Redis for caching, so that means it's definitely good to go. :)

Fallback

Thanks Chris! I'll look into that option. Good to know that Basecamp is using Redis as the cache store. Thanks, I'm really enjoying this performance related series :)

Fallback

Would you be up for connecting the same Redis as the cache store and sidekiq? I've ran into issues with this in the past.

Fallback

What were the issues you ran into? The key names should be scoped accordingly, but other than that, you shouldn't have any issues sharing it.


Fallback

Nice tutorial Chris! I've got 2 questions and would be nice to know your opinion.

What do you think about using

<% cache ['lists-index', @lists.map(&:id), @lists.map(&:updated_at).max] do %>

instead of

<% cache ['lists-index', "page-#{params[:page] || 1}", @lists.count, @lists.map(&:updated_at).max] do %>

?

Could you also take a look at this question from the recent questions thread? In many situations there are some parts of the page that depend on the user's role (current_user, etc.). I would like to know what approaches can be used in those cases.

Thanks!

Fallback

Yeah, you could probably do that too with the cache key. There are a lot of different ways to set it up, your goal is really just to make sure that the key gets updated when your database changes and that it only updates when needed. Sometimes that will depend on your app and certain cache keys will make more sense than others.

I'm hopping into the forum this morning to answer a bunch!


Fallback

Hey Chris. Do you have any tips on expiring childrens when parent changes, where simple touching doesn't apply. Imagine a table of students and their related classes. You cache row fragments. When name of the class changes, rarely, but can, you have to expire all student fragments of the changed class.

Fallback

Most cases like that, if you include both items in the cache key (both the user and the class) and use their updated_at timestamps there, it will do the trick. That way your cache changes anytime you update one or the other.


Fallback

Great job on this one. I've been wanting this feature for years. For multi-tenant apps that are setup using Postgres schema's, would it be best to override the cache key to include the tenant id so that it's totally not possible for Todo number 5 in tenant 1 to overlap with Todo number 5 in tenant 2? I know the updated_at makes this a remote possibility, BUT it's still possible. Thoughts?

Fallback

Yep, you'd need to include that in the cache key so they are all separated out cleanly. Don't want to be leaking any of that information between schemas.


Fallback

Awesome episode as always Chris.

What about the implications of using roles for some content within a partial that is cached? E.g. say I have a section that I only want to show to `current_user.has_role? :teacher`, but another user that doesn't have the role teacher is also viewing that page at the same time.

How does the built-in Russian Doll Caching stuff play with that scenario?

Edit: Actually Chris, I see that you did that already in the 'Advanced Caching with User Permissions and Authorization' epsiode. Thanks much and pleas ignore this question :)

Fallback

Yup, you can either use JS to hide / show functionality or you can also include the role in the cache key if you want. That will create caches for each role meaning you'll use more cache storage, but can cache each version separately. I'd still recommend using JS to hide / show things so you only have one cache per item.


Fallback

How would I cache content different for non-logged in users, logged in users, and the post owner? For example, Facebook "friends" can see your private posts.


Login or create an account to join the conversation.