WordPress get_posts Example: Fetch a Small Content Set Efficiently
Use get_posts() for compact homepage, sidebar, and plugin UI queries without disturbing the main loop or pagination behavior.
Published
April 28, 2026
Reading Time
2 min read
Updated
April 28, 2026

Implementation Notes
Extension points, code paths, and implementation choices that should survive contact with production.
Best For
WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.
Primary Topics
Editorial Focus
Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on April 28, 2026.
Full Report
Last reviewed: April 28, 2026
get_posts() is one of the fastest ways to fetch a small, controlled set of posts for a secondary UI block such as a related articles rail, homepage module, or plugin dashboard panel. The mistake is treating it like a full archive query and then wondering why pagination, template state, or global post handling gets messy.
This guide shows how to use get_posts() for a compact content fetch without disturbing the main query.
Fetch a small post list with explicit limits
<?php
$posts = get_posts(
array(
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => 4,
'orderby' => 'date',
'order' => 'DESC',
'ignore_sticky_posts' => true,
)
);
For a small homepage or sidebar block, this is usually better than changing the main query. Keep the result set tight and intentional.
Loop through the results and reset global state
if ( $posts ) {
foreach ( $posts as $post ) {
setup_postdata( $post );
?>
<article>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</article>
<?php
}
wp_reset_postdata();
}
If template tags like the_title() or the_permalink() are used inside the loop, always restore global post state afterward.
Request only the fields you really need
$post_ids = get_posts(
array(
'post_type' => 'post',
'numberposts' => 10,
'fields' => 'ids',
)
);
When later code only needs IDs for a cache warmup, exclusion list, or metadata lookup, returning IDs keeps the query lighter.
Use get_posts() for secondary content, not archive control
get_posts() is ideal for isolated blocks. If the goal is to change category archives, search results, or the blog index, that belongs in pre_get_posts or a dedicated WP_Query flow.
Production checklist
- Keep the result count small and explicit.
- Use
fields => 'ids'when full post objects are not needed. - Call
wp_reset_postdata()after template-tag loops. - Do not use this helper to replace archive pagination logic.
- Set
post_statusandpost_typeintentionally instead of relying on defaults. - Review sticky-post behavior when rendering editorial blocks.
Common mistakes
- Using it for the main archive query. That creates brittle pagination and routing behavior.
- Skipping
wp_reset_postdata(). Later template tags can render the wrong post. - Fetching too many rows. Small UI blocks do not need archive-sized queries.
- Assuming default arguments are safe enough. Be explicit about status, type, and ordering.
- Pulling full post objects when only IDs are needed. That adds unnecessary overhead.
Related reading
If the main archive query needs to change, use the pre_get_posts guide. If the fetched posts will be displayed with thumbnails, pair the output with the wp_get_attachment_image article.


