The concept of caching is not complicated: store the results of a query for a short period of time in a fast storage engine so you touch the slow and/or expensive database less. This simple concept often hides application-level complexity as not all queries should be cached. Deciding what to cache and what not to cache depends on many factors:
Will there be a performance benefit? Already short running queries may have negligible or even negative performance impacts when cached.
Are slightly stale results acceptable? Your application or users may be able to tolerate an out-of-date response for non-critical pieces but require as near to real-time as possible for others.
Does the query pollute your cache? A highly varied query pattern may result in your cache being overrun by data that provides little utility.
These issues lead to two conclusions:
- You can not universally cache all queries
- You need to be able to toggle the caching of queries for testing and profiling purposes
Unfortunately, most application-level caching libraries take an imperative approach to cache — the application developer needs to implement some sort of flow control to determine a given query should be cached. For each query that needs to be cached, this has to be uniquely implemented. Even if this a simple, abstracted library, it requires thought and creates a surface area for bugs and mistakes.
An alternate approach is to work declaratively — your actual application logic is unaffected the caching (or not) of a query, you only need to notate the query itself to dictate the caching. This talk will go over this pattern and its implementation as an add-on to the Node.js PostgreSQL client slonik, as well as the resulting effect on the caching engine, Redis.
Examples and a demo will be provided to show how this allows for quick and easy toggling and control of caching with only simple changes to queries but not the flow of the application itself.