After trying a few WP cache and CDN plugins it becomes pretty obvious that slow query is the real culprit and it doesn’t get cached by default. Things get even worse when you need to have a pagination. Flavio Tordini, an Italian developer, discovered that every time you run WP_Query or get_posts “…even when you don’t need pagination at all SQL_CALC_FOUND_ROWS tells MySQL to do additional work to count the total matching rows…” (flavio.tordini.org/speed-up-wordpress-get_posts-and-query_posts-functions).
Not having pagination was not an option but at least the queries needed to be cached in order to make my otherwise crippled blog well… usable. WP Transients is the solution. The queries will be temporarily stored in the database. According to “Speed Up Your WordPress by Caching Custom Queries using Transients API” article setting up the transients alone is a big improvement, but the article doesn’t mention that “transients are inherently sped up by caching plugins” (codex.wordpress.org/Transients_API).
WP Transients implementation is pretty straight forward. The only tricky part is generating individual “sub-transients” for paginated queries. Tag name concatenated with current page variable generates a unique transient name: