WP_Query vs query_posts vs get_posts vs pre_get_posts

Posted by Will on April 16, 2013

Quick Breakdown

  • query_posts – don’t use except in rare edge cases
  • pre_get_posts – use if you want to alter the default query on a page
  • new WP_Query – use to get different results from the main query
  • get_posts – same as WP_Query, just returns results in array format instead
  • query_posts

    Using query_posts is not recommended any more. There are better ways to accomplish what you’re trying to accomplish. Trying to alter the main query? Use the action pre_get_posts to filter the results(see below). query_posts throws the original main query to the side(after it has already been run), and creates a new main query. It replaces all post related global variables, and results in a completely new database call. There is simply no reason you shouldn’t just alter the existing query. I’m sure there are some edge cases where it should be used, but I can’t think of any off the top of my head. Use one of the options below, as they will more than likely be better suited.


    This is a filter. This modifies the main query to a page. So, for example, we want to change the number of results that are returned on the homepage…

    function tj_change_home_number($query){
        if ( is_home() ) {
            $query->set( 'posts_per_page', 2);
    add_action( 'pre_get_posts', 'tj_change_home_number');

    This would alter the main query to only return 2 posts on the homepage.


    The main query on any template that is called is an instance of WP_Query. When you interact with the global post variables within a template, that is the result of WP_Query. The use cases for this are numerous, but as with get_posts, I’d declare a new WP_Query for the purpose of pulling related posts, something along those lines. Just keep in mind that if you run the the_post() function while looping through a new WP_Query, run the function wp_reset_postdata() after you are done looping to reset the global post data to the original main query.


    By using get_posts, you are in effect calling a new WP_Query, and getting that information returned in an array format. I will typically use get_posts when I’m returning posts for a slider on the homepage, or calling some related posts in a sidebar. WP_Query could just as easily be used, but its a good way to receive an array of posts without modifying the global post variables. In my view its the most simplistic and easiest to use. There are no function calls necessary after your data is returned, just looping through an array.

    This can be a little confusing, so feel free to ask questions in the comments below.


Leave a Reply

Your email address will not be published. Required fields are marked *