I miss Rails's Russian Doll caching


I’m a Rails developer who is new to Hanami, and so far I like a lot of what I’m seeing :smiley:

One thing I am missing a lot from Rails however, is Russian doll caching. I am guessing the reason it’s not there, is related to Hanami’s staunch belief that all data required for a view should be loaded in as few queries as possible, preferably just one, and that the nemesis of performance is N+1 queries. If all the data required for a view is available, then Russian doll caching isn’t very valuable.

However, consider this example. I have a relation Accounts, and each account has a number of associated relations. Say I want to list all accounts:

Account Followers Posts Outstanding invitations Highest voted post
Alice 205 34 0 How to fix bugs
Bob 19 304 2 How to log out?
Carol 23 9 0 Preferred color of shed?

As you can see, to get all the data for this view requires joining and aggregating many tables. It could get very expensive if the tables are big and the joins are complex. In Rails what I would do, is to embrace N+1 and rely on Russian Doll caching to ensure I don’t actually hit the DB N+1 times. If each row changes relatively infrequently, this is potentially cheaper than fetching all the data in one query (YMMV of course).

Am I missing something fundamental? How would you solve this in Hanami?


Your assumption makes sense for all the apps, regardless of Hanami. But that isn’t the reason why we don’t have caching.

The answer is simpler: we didn’t implement because we simply didn’t plan it. It would be an amazing feature to have, but it’s a complex beast that we didn’t had the workforce to implement.


Maybe not Russian Doll but talking about caching generally I wonder if https://github.com/sorentwo/readthis would be a good choice to use for caching in hanami.


@buszu Thanks for the suggestion, but readthis is a backend.

The most important (and difficult) part of the template caching (a-là Russian Doll), is the caching strategy itself. For instance when evaluating a template if cache a fresh content, or serve it from cache if already cached content, or to expire the cache if stale…