WP_Query is a powerful tool for fetching posts in WordPress. However, if you don’t carefully configure your queries, they can quickly become inefficient, particularly on larger sites. Whether you’re working on a high-traffic website, a REST API endpoint, or an Ajax-powered interface, the way you configure WP_Query can make a significant difference in performance.
In this post, we’ll walk through key parameters you can use to improve the speed of your queries, reduce memory consumption, and optimise WordPress’s database interactions.
Key Parameters for Improving WP_Query Performance
1. posts_per_page
The posts_per_page parameter directly controls the number of posts returned by the query. If you only need one post, set posts_per_page to 1 to reduce unnecessary load.
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 1,
]);
Code language: PHP (php)
Best practices:
- Use 1 if you only need a single post.
- Keep result sets under 100 posts unless paginating or processing in batches.
- Avoid -1 (to get all posts), as this can quickly consume memory on larger sites.
2. no_found_rows
By default, WordPress calculates the total number of matching posts for a query. This is useful when you’re paginating results, but if you don’t need pagination, you can disable this calculation.
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 10,
'no_found_rows' => true,
]);
Code language: PHP (php)
Use when: You don’t need pagination, such as on homepage widgets or API responses.
3. ignore_sticky_posts
Sticky posts are displayed at the top of a list of posts, which adds extra complexity to the query. If sticky posts aren’t important for your use case, you can tell WordPress to ignore them.
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 10,
'ignore_sticky_posts' => true,
]);
Code language: PHP (php)
Use when: You don’t need sticky posts interfering with your query, such as in custom feeds or filtered post lists.
4. update_post_meta_cache, update_post_term_cache, and update_menu_item_cache
These parameters control whether WordPress preloads associated metadata, taxonomy terms, and menu item data for each post. If you’re not using these features, disabling them can save memory and improve query speed.
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 10,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'update_menu_item_cache' => false,
]);
Code language: PHP (php)
Use when: You’re only displaying basic post data (like IDs or titles) or intend to fetch metadata or terms later.
⚠️ Important: update_menu_item_cache should only be enabled when querying nav_menu_item post types. For other post types, leave it disabled to avoid unnecessary overhead.
5. fields
The fields parameter controls which parts of the WP_Post object are returned. If you only need specific data (e.g., just the post IDs), setting this to ‘ids’ can reduce memory usage and improve performance.
$query = new WP_Query([
'post_type' => 'post',
'fields' => 'ids',
]);
Code language: PHP (php)
Options:
- ‘all’ – Returns full post objects (default).
- ‘ids’ – Returns an array of post IDs.
- ‘id=>parent’ – Returns an associative array of IDs and their parent IDs.
Use ‘ids’ or ‘id=>parent’ when you don’t need the full post object, such as for bulk processing.
6. cache_results (Use with Caution)
This parameter controls whether the query results are cached. Although disabling query caching might seem like a performance boost, it’s generally not recommended, especially since WordPress 6.1 introduced enhanced query caching.
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 10,
// cache_results => true (default)
]);
Code language: PHP (php)
Avoid setting to false unless you’re running batch scripts or WP-CLI commands where query reuse isn’t needed. In normal requests, leaving cache_results enabled is generally the best approach as it reduces repeated database hits.
See: WordPress 6.1 Query Caching Improvements
7. orderby => ‘rand’
Using orderby => ‘rand’ is tempting for displaying random posts, but it’s highly inefficient, particularly on large datasets.
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 5,
'orderby' => 'rand', // ⚠️ Expensive and not cacheable
]);
Code language: PHP (php)
Why it’s problematic:
- Not cacheable – Since the result changes every time, caching plugins can’t reuse it.
- Slow at scale – ORDER BY RAND() is inefficient on large databases, requiring a random number for every row.
- Increases load – It adds extra stress to your database.
Alternatives:
- Cache random results in a transient.
- Shuffle post IDs in PHP after performing a normal query.
- Use custom meta values to rotate content.
8. suppress_filters => false
The suppress_filters parameter disables all filters on a query, including important ones for caching and other plugin integrations. This can severely impact performance, particularly if you’re using caching plugins or multilingual tools.
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 10,
'suppress_filters' => true, // ⚠️ Not recommended
]);
Code language: PHP (php)
Why you should avoid it:
- Breaks caching plugins (e.g., Redis, Memcached) that rely on query filters.
- Disables multilingual plugins like WPML or Polylang, which rely on query hooks.
- Disables other performance enhancements or custom behaviour (e.g., SEO filters, membership-based content filtering).
Instead, use get_posts(), which does not require disabling filters and is generally a safer option for simpler queries.
9. meta_query Without Indexing
Using meta_query to filter posts based on custom fields can be very slow if the meta_key is not indexed. For large datasets, queries on non-indexed meta fields can drastically reduce performance.
$query = new WP_Query([
'post_type' => 'post',
'meta_query' => [
[
'key' => 'custom_field_key',
'value' => 'some_value',
'compare' => '='
]
],
]);
Code language: PHP (php)
Why it can be problematic:
- No indexes on meta_key or meta_value can cause slow queries, particularly on large datasets.
- Poor performance as WordPress must scan the postmeta table for every query.
What to do:
- Index your meta keys to improve query performance.
- Avoid LIKE queries, which are slower than exact matches.
- Consider custom tables for high-volume metadata.
10. Faster Taxonomy Queries with term_taxonomy_id
If you’re querying posts by taxonomy, you can optimise performance by querying by term_taxonomy_id directly. This avoids unnecessary joins and can significantly speed up the query.
$query = new WP_Query([
'tax_query' => [
[
'taxonomy' => 'category',
'field' => 'term_taxonomy_id',
'terms' => [23, 47],
'include_children' => false,
],
],
]);
Code language: PHP (php)
Why this improves performance:
- Avoids extra SQL joins and lookups in the terms and term_taxonomy tables.
- Reduces complexity in the SQL query and improves speed, especially with large datasets.
11. Optimising Queries with post__in
When using the post__in parameter to query a specific set of posts by their post IDs, you can improve performance by setting the posts_per_page parameter to match the count of the post IDs array.
$post_ids = [1, 2, 3, 4, 5]; // Array of post IDs
$query = new WP_Query([
'post_type' => 'post',
'post__in' => $post_ids,
'posts_per_page' => count( $post_ids ), // Match posts_per_page with array length
]);
Code language: PHP (php)
Why this improves performance:
- Setting posts_per_page to the count of the post ID array ensures the query doesn’t needlessly paginate or fetch extra posts.
- It optimises the query to exactly match the requested set of posts, reducing unnecessary overhead.
12. Use get_post() Instead of WP_Query for Single Posts
If you already have the post ID and only need to retrieve one post, you can bypass WP_Query entirely and use the simpler and more efficient get_post() function.
$post = get_post( 123 ); // Retrieve post by ID
Code language: PHP (php)
Why it’s better:
- get_post() is much faster than WP_Query when you’re only querying one post by its ID.
- It avoids the overhead of running a full query and retrieving unnecessary data, making it ideal for scenarios like displaying a single post or working with a post ID that has already been determined.
Conclusion
Optimising WP_Query isn’t just about writing fast queries — it’s about writing efficient queries that avoid unnecessary database operations, reduce memory usage, and integrate well with caching mechanisms.
By making thoughtful decisions around parameters like no_found_rows, ignore_sticky_posts, and meta_query, you can dramatically improve performance on your site. Avoiding common pitfalls like orderby => ‘rand’ and suppress_filters => true will also help ensure your queries are both fast and compatible with caching layers and plugin integrations.
You must be logged in to post a comment.