I just did an action on the query using pre_get_posts and it didn't work. When I removed the $query->is_main_query() it did work.

So, how do you know that what is the main query. I know there is the function is_main_query. What I am asking is there a way to tell which one you are looking at? How does WordPress know which one is the main query? If you have three or four going for different reasons such as categories, post types, pages. which is the main?

  • 3
    Try to answer your own Q after reading this: You don't know Query. And this: When should you use WP_Query vs query_posts() vs get_posts()?
    – brasofilo
    Commented Jan 14, 2013 at 3:58
  • nope. Still didn't do it for me. Obviously the query that I was changing with pre_get_posts wasn't the main query. But then that still leaves the question. If that wasn't the main query, which one is? The loop is the standard loop. I didn't use query_posts, get_posts or wp_query. Rather the_loop does but why is that loop not the main query? Not sure I am explaining myself correctly. I don't like those little slide shows you linked to. They usually leave a lot of information. Like they are cliff notes that someone wrote up for a speech. If you miss the speech you can't follow along very well.
    – Jamie
    Commented Jan 14, 2013 at 4:10
  • ps. Why did you migrate this from meta? what is the difference between the two sites?
    – Jamie
    Commented Jan 14, 2013 at 4:12
  • 1
    Read the faq of both and you'll know. That slide is from a Lead WordPress Developer, I think this is the presentation.
    – brasofilo
    Commented Jan 14, 2013 at 4:14
  • 1
    For future reference, posting relevant template/loop code would be especially helpful for defining context, and identifying details specific to your problem. @Rarst provides an excellent general answer, but without seeing your actual code, we can't help determine why the loop that you expect to be the main query isn't being recognized by WordPress as the main query. Commented Jan 16, 2013 at 4:05

1 Answer 1


WP_Query->is_main_query() method source (which function of same name calls) is very short and simple:

function is_main_query() {
    global $wp_the_query;
    return $wp_the_query === $this;

The main query is the query that is stored in $wp_the_query global. But what is that global? When WP sets up main query it stores it in two places: $wp_the_query and $wp_query. Latter is more known because that variable is what you commonly use to work with main query and what query_posts() changes.

However query_posts() works like this:

function query_posts($query) {
    $GLOBALS['wp_query'] = new WP_Query();
    return $GLOBALS['wp_query']->query($query);

It break link between $wp_query and $wp_the_query. And the reverse can be performend by wp_reset_query() to re-establish that:

function wp_reset_query() {
    $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];

So main query is the one that WP set up during core load.

It is typically what $wp_query holds, unless it was modified not to be main query anymore.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.