How to Sort Posts by Custom Field Value in WordPress

December 18, 2025
How to Sort Posts by Custom Field Value in WordPress

Sorting posts by a custom field (post meta) is a common requirement in WordPress: price, rating, event date, priority, “featured” flags, and more. The correct solution depends on the field type (number, text, date) and where you want the sorting to apply (a custom loop, an archive, or admin).

This guide shows reliable patterns for sorting posts by custom field value, including numeric sorting, date sorting, ACF fields, and multi-level sorting.


1) Sort a Custom Query by a Meta Field

The basic pattern uses meta_key and orderby.

$query = new WP_Query( array(
  'post_type'      => 'post',
  'posts_per_page' => 10,
  'meta_key'       => 'my_field',
  'orderby'        => 'meta_value',
  'order'          => 'ASC',
) );

Use this when your meta value is plain text and alphabetical sorting is fine.


2) Sort Numerically (Most Common Mistake)

If your custom field stores numbers (e.g., 10, 2, 100), you must sort with meta_value_num. Otherwise, WordPress sorts as strings (so 100 comes before 2).

$query = new WP_Query( array(
  'post_type'      => 'post',
  'posts_per_page' => 10,
  'meta_key'       => 'price',
  'orderby'        => 'meta_value_num',
  'order'          => 'ASC',
) );

Use meta_value_num for: prices, ratings, priority, sort order, counts, scores.


3) Sort by a Date Stored in a Custom Field

Date sorting is only reliable if your meta is stored in a sortable format. Recommended formats:

YYYYMMDD (example: 20251219) or YYYY-MM-DD (example: 2025-12-19)

If your field is YYYYMMDD

$query = new WP_Query( array(
  'post_type'      => 'event',
  'posts_per_page' => 10,
  'meta_key'       => 'event_date',
  'orderby'        => 'meta_value',
  'order'          => 'ASC',
) );

If your field is a real date string and you want strict date handling

Use a meta query with type set to DATE (works best with YYYY-MM-DD).

$query = new WP_Query( array(
  'post_type'      => 'event',
  'posts_per_page' => 10,
  'meta_key'       => 'event_date',
  'orderby'        => 'meta_value',
  'order'          => 'ASC',
  'meta_query'     => array(
    array(
      'key'  => 'event_date',
      'type' => 'DATE',
    ),
  ),
) );

4) Sort While Excluding Posts Missing the Field

If some posts don’t have the meta key at all, the sort can feel “random.” You can require the field to exist:

$query = new WP_Query( array(
  'post_type'      => 'post',
  'posts_per_page' => 10,
  'meta_key'       => 'priority',
  'orderby'        => 'meta_value_num',
  'order'          => 'DESC',
  'meta_query'     => array(
    array(
      'key'     => 'priority',
      'compare' => 'EXISTS',
    ),
  ),
) );

This is useful for “featured first” layouts where only some posts are prioritized.


5) Sort Featured Posts First, Then Newest

Common requirement: show featured posts first (custom field is_featured = 1), then sort the rest by date.

$query = new WP_Query( array(
  'post_type'      => 'post',
  'posts_per_page' => 10,
  'meta_key'       => 'is_featured',
  'orderby'        => array(
    'meta_value_num' => 'DESC',
    'date'           => 'DESC',
  ),
  'meta_query'     => array(
    array(
      'key'     => 'is_featured',
      'compare' => 'EXISTS',
    ),
  ),
) );

Tip: Ensure your featured field is consistently stored (e.g., 1 or 0), not “yes/no” strings.


6) Sorting on Archives with pre_get_posts

If you want a CPT archive to always sort by a field (e.g., events by event_date), use pre_get_posts.

add_action( 'pre_get_posts', function( $query ) {

  if ( is_admin() || ! $query->is_main_query() ) {
    return;
  }

  if ( is_post_type_archive( 'event' ) ) {
    $query->set( 'meta_key', 'event_date' );
    $query->set( 'orderby', 'meta_value' );
    $query->set( 'order', 'ASC' );

    $query->set( 'meta_query', array(
      array(
        'key'     => 'event_date',
        'compare' => 'EXISTS',
      ),
    ) );
  }

} );

This keeps templates clean and ensures consistent sorting site-wide.


7) Sorting by an ACF Field

ACF stores values in post meta, so sorting is the same as any custom field. The key point is: use the correct sort type for how the value is stored.

  • ACF number field → meta_value_num
  • ACF date picker stored as Ymdmeta_value works well
  • ACF true/false → meta_value_num

Example (ACF date picker stored as Ymd):

$query = new WP_Query( array(
  'post_type'      => 'event',
  'posts_per_page' => 10,
  'meta_key'       => 'event_date',
  'orderby'        => 'meta_value',
  'order'          => 'ASC',
) );

8) Common Pitfalls (And Fixes)

“My numeric sorting is wrong”

Use meta_value_num, not meta_value.

“Posts without the field appear in strange positions”

Add a meta query with EXISTS (or set a default value for every post).

“Sorting is slow on large sites”

Meta sorting can be expensive. Keep it fast by:

  • Sorting on one key (avoid deep meta_query complexity unless needed)
  • Ensuring consistent meta values exist
  • Limiting result sets (pagination)
  • Considering a dedicated “sort_order” numeric field for complex ordering

Conclusion

Sorting posts by custom fields is straightforward once you match the sorting method to the data type:

  • Text → meta_value
  • Numbers → meta_value_num
  • Dates → store as YYYYMMDD or YYYY-MM-DD, then sort consistently

Key takeaway: Always decide whether the meta value should be treated as text, a number, or a date — and choose orderby accordingly.

Avatar

Written by

satoshi

I’ve been building and customizing WordPress themes for over 10 years. In my free time, you’ll probably find me enjoying a good football match.