I'm working at a WordPress theme. Since I need to display featured posts, related posts, some widgets with recent posts and so on, I need to use multiple custom loops. Because of this, the number of database queries have also increased. In an attempt to optimize the theme for better performance I came across http://codex.wordpress.org/Transients_API , which seems like a good way to cache the loops that I don't need to be updated to every page reload. So far so good, I used transient for wp_nav_menu and it worked as it should. I managed to decrease a bit the number of db queries. The problem occured when I tried to use the transient for custom loops. The transient is saved. I can get the transient value. The only problem is that the number of the database queries seems to be significantly higher than when using WP_Query without a transient. Here is my custom loop: if(false===( $loop = get_transient('featured'))) { $loop =new WP_Query( array('posts_per_page'=>20)); set_transient('featured', $loop,60* MINUTE_IN_SECONDS); } if( $loop->have_posts()): while( $loop->have_posts()): $loop->the_post(); the_title(); the_post_thumbnail('thumb'); endwhile; endif; wp_reset_postdata(); PHP: The code used to display the number of database queries and execution time is the following: <?php echo get_num_queries();?> queries in <?php timer_stop(1);?> seconds. PHP: I can't explain why the number of database queries increases instead of decreasing and why this worked for menues, but not for custom loops. Maybe I missed something. Any help is appreciated.
Never mind. I've managed to do what I wanted in another way based on Pieter Goosen answer from stackexchange. For some reasons, the example given in WordPress codex about how you can store the value of a query object into a transient was wrong. It seems that WordPress will use additional queries to determine the post categories, even you are getting the query object from transient, so, you will end with more queries than when using a direct DB query. Instead of storing the entire query object, you can store only the values that you need into a transient (like post title, permalink, id, thumbnail url or anything that you can get inside WordPress loop), and recover theese values afterwards. So, instead of using a WP_Query each time a user reload respective page (this will generate multiple DB queries according to the number of posts you want to grab and posts info), your loop will use the information stored in transient (using only 2 database queries to grab any number of posts and data). This will make your website to load faster and to use lower server resources (without a cache plugin). Below is a working example: <?php if( false === ( $transient = get_transient('featured-content') ) ) { // Use Wp_query and set a transient $featured = new WP_Query( $args ); while( $featured->have_posts() ) : $featured->the_post(); $title = get_the_title(); $permalink = get_the_permalink(); $thumbnail = get_the_post_thumbnail( get_the_ID(), 'full'); echo $thumbnail; ?> <a class="item-title" href="<?php echo esc_url( $permalink ); ?>"><?php echo esc_html( $title ); ?></a> <?php // Save transient value $value[] = array( 'title' => $title, 'permalink' => $permalink, 'thumbnail' => $thumbnail ); endwhile; set_transient( 'featured-content', $value, 60*60 ); wp_reset_postdata(); } else { // Get transient values foreach ( $transient as $key ) { $title = $key['title']; $thumbnail = $key['thumbnail']; $permalink = $key['permalink']; echo $thumbnail; ?> <a class="item-title" href="<?php echo esc_url( $permalink ); ?>"><?php echo esc_html( $title ); ?></a> } } ?> PHP: This example will store post title, permalink and thumbnail into a transient that will expire in 60 min. After this time, when the first user loads a page, a new transient will be set. Your WordPress theme will continue to use the values stored in the transient until the transient will expire and so on. I hope this explanation will be helpful to someone who has experienced the same problem.