WP Mayor is supported by its audience. Our recommendations are based on our experts’ research and hands-on testing. If you purchase through a link on our website, we may earn a commission. Here’s why you can trust us.

When should you use WP_Query vs query_posts() vs get_posts()?

  Introduction

I recently came across a fantastic diagram by Rarst showing the difference between WP_Query(), query_posts() and get_posts(). As you may know, these are all ways of retrieving posts in WordPress, but they are not all equal.

WP Mayor is supported by its audience. Our recommendations are based on our experts’ research and hands-on testing. If you purchase through a link on our website, we may earn a commission. Here’s why you can trust us.
 Table of contents

Update: A better way of thinking about the loop can be seen in the following talk and slides by Andrew Nacin, plus a written explanation by John James Jacoby if you are more inclined to understand things that way:

Nacin: http://wordpress.tv/2012/06/15/andrew-nacin-wp_query/

Jacoby: http://developer.wordpress.com/2012/05/14/querying-posts-without-query_posts/

Thanks goes to Konstantin Kovshenin for pointing this out (see comment below)


I recently came across a diagram in a WordPress Stackexchange answer by Rarst showing the difference between WP_Query(), query_posts() and get_posts(). As you may know, these are all ways of retrieving posts in WordPress, but they are not all equal.

Here’s the difference:

  • query_posts() might be used in one and only case if you need to modify main query of page (for which there are better and more reliable methods to accomplish, over simplistic approach of this function). It sets a lot of global variables and will lead to obscure and horrible bugs if used in any other place and for any other purpose;
  • get_posts() is very similar in mechanics and accepts same arguments, but returns array of posts, doesn’t modify global variables and is safe to use anywhere;
  • WP_Query class power both behind the scenes, but you can also create and work with own object of it. Bit more complex, less restrictions, also safe to use anywhere.

Here’s another post which is worth a read:

http://digwp.com/2011/05/loops/

If you enjoyed this post, make sure to subscribe to WPMayor’s RSS feed.

Jean Galea
Jean Galea
Jean Galea is an investor, entrepreneur, and blogger. He is the founder of WP Mayor, the plugins WP RSS Aggregator and Spotlight, as well as the Mastermind.fm podcast. His personal blog can be found at jeangalea.com.
Recommended For You
Recommended For You
Get more expert advice like this delivered to your inbox every week.
Join thousands of designers, developers, and marketers who trust our experts to find and test the best tools and services for your website.
By signing up to our newsletter, you agree to receive electronic communications from WP Mayor that may include advertisements.
Get more expert advice like this delivered to your inbox every week.
Join thousands of designers, developers and marketers who trust our experts to find and test the best tools to build, improve, and optimize their websites.
By signing up to our newsletter, you agree to receive electronic communications from WP Mayor that may include advertisements.
Join the Conversation

6 Responses

  1. Hi, Jean Galea

    Nice post! Now, I know the difference. For me, it turned out better using WP_Query. Thanks 😀

  2. That answer is originally two years old and nowadays people are eager to poke holes in it, so I did new editorial pass there. 🙂 Also why push again query_posts() is now thankfully much more prominent, newer techniques does not really invalidate basic loop mechanics in template stage (which is all my answer and diagram were essentially about).

    Also if you are copying content in full from WPSE answer please make it clear under terms of the license (CC-BY-SA) and consider following attribution requirements http://blog.stackoverflow.com/2009/06/attribution-required/

  3. query_posts() might be used in one and only case if you need to modify main query of page (for which there are better and more reliable methods to accomplish, over simplistic approach of this function).

    Wrong 🙂 All three methods (query_posts, new WP_Query and get_posts) will issue a new query, so all three must be used in one and only one case: a secondary loop. If you want to modify the primary (main) loop you should do that before the query runs and the two best places for that are: the pre_get_posts action, and the request filter.

    It sets a lot of global variables and will lead to obscure and horrible bugs if used in any other place and for any other purpose

    It really just sets only one — the $wp_query global 🙂 It actually destroys it first though! It destroys the link to $wp_the_query and assigns a new WP_Query to $wp_query, and wp_reset_query restores back the link to $wp_the_query. It’s quite simple and straightforward if you read the wp-includes/query.php file.

    Actually I’m tired of repeating this over and over again, so why don’t we all just go and watch Nacin’s talk about WP_Query which has been hanging on the homepage of WordPress.tv for ages now:

    http://wordpress.tv/2012/06/15/andrew-nacin-wp_query/

    And if you ask me, query_posts should be deprecated. Without warning.

    ~ K

    1. +1 Konstantin!

      better to create one’s own content than republishing others content without really understanding it…

Leave a Reply

Your email address will not be published.

From web hosting to WooCommerce plugins and backup services, we have put together a collection of exclusive coupons and deals just for you.
WP Mayor_Icon_white

Reader Survey

Supercharge your WooCommerce store!