HPOS (Custom Order Tables) compatibility
Advanced Subscriptions is HPOS-native. It reads and writes subscriptions through WooCommerce's Custom Order Tables interface, not the legacy wp_posts table. There is no CPT fallback shim: on a fresh site, HPOS is the only storage path the plugin uses.
What HPOS is, in one paragraph
HPOS (High-Performance Order Storage) is WooCommerce's order data backend introduced in WC 7.1 and made the default for new installs in WC 8.2. Orders, refunds and subscriptions live in dedicated tables (wc_orders, wc_order_addresses, wc_order_operational_data, wc_orders_meta) instead of wp_posts and wp_postmeta. The result: faster queries, cleaner schemas, and no more "shop_order" custom post type clogging the posts table.
Prerequisites
- WooCommerce 8.2 or later. Earlier versions support HPOS as opt-in; we tested down to WC 7.1 but recommend 8.2+.
- PHP 7.4+ (PHP 8.x recommended for the indexes HPOS leans on).
- Every other active extension that touches orders must declare HPOS compatibility. WooCommerce shows a banner under WooCommerce → Settings → Advanced → Features listing any incompatible plugin by name.
Enabling HPOS
- Go to WooCommerce → Settings → Advanced → Features.
- Under Custom order tables, choose High-performance order storage (new).
- WooCommerce migrates existing orders in the background via Action Scheduler. The job is incremental; the store stays usable while it runs.
- When the migration finishes, tick Enable compatibility mode off to stop dual-writing to
wp_posts. This is the point of no return for that store; keep a backup.
Coexistence with non-HPOS extensions
If one of your other plugins hasn't declared HPOS compatibility, two paths are open:
- Keep compatibility mode on. WooCommerce dual-writes to both
wp_postsand the new tables. Performance gain is partial, but the incompatible plugin keeps working. This is the safe default while you wait for the other vendor to ship the update. - Disable that plugin and switch HPOS fully on. The store gets the full speed-up; you lose the feature the other plugin provided until it's updated.
Advanced Subscriptions doesn't dictate this choice. We work in either mode.
How the plugin uses HPOS
- Reads via
wc_get_order()andwc_get_orders()withtype => 'aswc_subscription'. No directWP_Queryagainst the posts table. - Writes via the standard
WC_Order::save()API. The plugin extendsWC_Orderfor itsASWC_Subscriptionclass, so the data layer is HPOS-native automatically. - Indexes we depend on for renewal queries:
type,status, and the operational columnsdate_paid_gmtanddate_completed_gmt. All of these are part of the HPOS schema.
Relevant hooks
aswc_subscription_query_args— filter the args used bywc_get_orders()when the plugin queries subscriptions. HPOS-aware.aswc_subscription_object_class— swap the PHP class instantiated for a subscription. Useful for HPOS-aware extensions that wrap our object.