May 4, 2025

Deep Dive into WooCommerce HPOS (High-Performance Order Storage)

WooCommerce HPOS (High-Performance Order Storage) is a major enhancement designed to improve the performance of order management in WooCommerce, especially for stores with a high volume of orders. In this blog post, we’ll explore what HPOS is, how it works, its database structure, performance improvements, and how developers can adapt their plugins and code to work seamlessly with HPOS.


Why HPOS?

WooCommerce originally stored orders as a custom post type (shop_order), using the standard WordPress wp_posts and wp_postmeta tables. As WooCommerce evolved and stores grew larger, this architecture became a performance bottleneck due to the inefficiency of querying large volumes of postmeta data.

To resolve this, the WooCommerce team introduced HPOS, a new way of storing order data using dedicated custom tables. As of WooCommerce version 8.2, HPOS is enabled by default for all new stores.


What is HPOS?

HPOS stands for High-Performance Order Storage. Instead of storing orders as custom post types, WooCommerce now uses a set of purpose-built database tables to store order-related information. This significantly improves performance by reducing the need to query generic WordPress tables.

Key HPOS Tables

HPOS introduces several new tables:

  • wp_wc_orders: Stores core order information.
  • wp_wc_order_addresses: Stores billing and shipping addresses.
  • wp_wc_order_operational_data: Stores operational data like order status that changes frequently.
  • wp_wc_orders_meta (optional): Similar to wp_postmeta, this table can be used by third-party plugins to store additional metadata.

Performance Comparison

Let’s look at a real-world SQL example to highlight the performance improvements:

Classic CPT-Based Query

SELECT wp_posts.ID
FROM wp_posts
INNER JOIN wp_postmeta AS country ON wp_posts.ID = country.post_id AND meta_key = '_billing_country'
WHERE wp_posts.post_type = 'shop_order'
AND country.meta_value = 'DK'

HPOS-Based Query

SELECT wp_wc_orders.id
FROM wp_wc_orders
INNER JOIN wp_wc_order_addresses AS address ON address.order_id = wp_wc_orders.id AND address.address_type = 'billing'
WHERE address.country = 'DK'

For a store with around 5,000 orders, the HPOS query can be up to 4 times faster, especially because it avoids the bloated wp_postmeta table.


Enabling HPOS

To enable HPOS:

  1. Go to WooCommerce > Settings > Advanced > Features.
  2. Toggle High-Performance Order Storage to enable it.

Things to Note

  • Enabled by default in WooCommerce 8.2+ for new stores.
  • You cannot enable HPOS if incompatible plugins are active.
  • Pending orders may need to be synchronized before switching.
  • Compatibility mode allows HPOS and CPT-based storage to coexist (not recommended for performance, but good for plugin compatibility).

Making Your Plugin Compatible

If your plugin uses WP_Query, get_post_meta(), or other WordPress core functions to handle orders, it may not work correctly with HPOS.

The best practice is to use WooCommerce’s CRUD-based methods. If you already use WC_Order, you may not need to change anything.

Examples

Fetching an Order:

$order = wc_get_order( $order_id );
$order_status = $order->get_status();

Querying Orders:

$query = new WC_Order_Query( array( 'limit' => 10 ) );
$orders = $query->get_orders();

Checking Order Type:

use Automattic\WooCommerce\Utilities\OrderUtil;

if( 'shop_order' === OrderUtil::get_order_type( $post_id ) ) {
    // Do something
}

Order Placeholders

Each HPOS order also creates a placeholder post (shop_order_placehold) in wp_posts. These placeholders exist for backward compatibility but contain minimal data.


Detecting HPOS Programmatically

To check whether HPOS is enabled:

use Automattic\WooCommerce\Utilities\OrderUtil;

if( OrderUtil::custom_orders_table_usage_is_enabled() ) {
    // HPOS is enabled
}

Declaring Plugin Compatibility

To prevent WooCommerce from allowing HPOS with an incompatible plugin, you can declare this:

add_action( 'before_woocommerce_init', function() {
    if( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
            'custom_order_tables',
            __FILE__,
            false // Set to true if compatible
        );
    }
});

Screen ID Changes

Since orders are no longer posts, the screen ID for the order list has changed from edit-shop_order to woocommerce_page_wc-orders.

Example: Show Admin Notice on Order Page

add_action( 'admin_notices', function() {
    $screen = get_current_screen();
    if( 'woocommerce_page_wc-orders' === $screen->id ) {
        echo '<div class="notice notice-info"><p>Hey there</p></div>';
    }
});

Example: Add Custom Column to Order List

add_filter( 'manage_woocommerce_page_wc-orders_columns', function( $columns ) {
    $columns['misha_column'] = 'Info from Misha';
    return $columns;
});

Conclusion

WooCommerce HPOS is a powerful update that addresses long-standing performance issues in order management. For developers and store owners, understanding the new data structure and switching to WooCommerce’s official methods will unlock better performance, especially at scale. While it may take some effort to migrate or update existing code, the benefits in speed and scalability are well worth it.