I have a quite extensive database, 30000+ items, and using this:

$args = array(
    'posts_per_page'  => -1,
    'post_type'       => 'books',
    's'               => $s

$post_counts = count(get_posts($args));

seems to take forever.

I solved this particular case with:

$post_count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'books' AND post_status = 'publish' AND post_title LIKE '%".$s."%'");

But I have many queries that I'd like to count without having to write them by hand. Is there any way to count the posts with the $args using wordpress native functions without having to store the whole querie but only the count?


Here's one thing you could do. Create a WP_Query object but only include ids:

$args = array(
    'posts_per_page'    => -1,
    'post_type'         => 'books',
    's'                 => $s,
    'fields'            => 'ids',

$query          = new WP_Query( $args );
$post_counts    = $query->post_count;

By using fields => ids you're only returning the IDs. Also, WP_Query already does a count and supplies it as a property: post_count. Finally, since we are using a WP_Query we need to reset the globals with wp_reset_postdata().


When WP_Query generates a SQL query with SQL_CALC_FOUND_ROWS and a LIMIT clause:


then the total number of rows:


is available from the found_posts property of WP_Query.

This means we can fetch a single post with:

'posts_per_page' => 1 // not -1

and get the total count from

$total = $query->found_posts;

where $query is the WP_Query object.

From the MySQL documentation:


For a SELECT with a LIMIT clause, the number of rows that would be returned were there no LIMIT clause

It's also informative to look at WP_Query::set_found_posts() to see how the found_posts property is constructed.


There is $wpdb->num_rows parameter. But I suggest you do it with

$wpdb->get_var("SELECT COUNT(*) ... )

This should be much faster if I am not mistaken. It's related to mysql internal functions.

When doing COUNT, the server will only allocate memory to store the result of the count.
When using mysql_num_rows, the server will process the entire result set, allocate memory for all those results

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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