MS-M

HPOS w WooCommerce - co to jest, czy warto włączyć i jak to zrobić bez utraty zamówień

W panelu WooCommerce, w zakładce Ustawienia → Zaawansowane → Funkcje, jest pole "Przechowywanie danych zamówień" z dwiema opcjami: "Magazyn wpisów WordPressa (przestarzałe)" i "Wydajne przechowywanie zamówień (zalecane)". Ta druga opcja to HPOS. Jeśli twój sklep powstał przed końcem 2023 roku, jest spora szansa, że nadal stoi na tej pierwszej - i że ktoś ci powiedział, żeby "to przełączyć", ale nikt nie wyjaśnił, co się wtedy dzieje z zamówieniami.

Ten wpis otwiera na moim blogu serię bazy wiedzy WooCommerce: teksty dla technicznych właścicieli sklepów i developerów, bez oferty w środku. Wszystko, co niżej, sprawdziłem na WooCommerce 11.0.1 i 10.6.0 (wrzesień 2026). Różnica między tymi wersjami ma znaczenie, bo w 10.7 WooCommerce zmienił jedną rzecz, o której w polskich tekstach o HPOS nie ma ani słowa.

HPOS w WooCommerce - zamówienia przeniesione z jednego przepełnionego magazynu do czterech uporządkowanych regałów

Krótka odpowiedź (dla niecierpliwych)

HPOS (High-Performance Order Storage) to sposób przechowywania zamówień WooCommerce w osobnych, dedykowanych tabelach bazy danych, zamiast w ogólnych tabelach wpisów WordPressa (wp_posts i wp_postmeta). Od WooCommerce 8.2 (październik 2023) jest domyślny w każdej nowej instalacji. Warto go włączyć w każdym sklepie, w którym wtyczki i własny kod są z nim zgodne. Nie warto włączać go na siłę, gdy w sklepie działa krytyczna wtyczka bez zgodności albo nikt nie ma czasu przetestować przełączenia na kopii sklepu.

Jeśli prowadzisz sklep i nie piszesz kodu, wystarczą ci sekcje "co zmienia", "co się stało w 10.7" i "kiedy nie włączać". Jeśli jesteś developerem, reszta jest dla ciebie.

Jak WooCommerce trzymał zamówienia do wersji 8.2 - i dlaczego to bolało

WooCommerce powstał jako wtyczka do WordPressa, a WordPress jest systemem do publikowania treści. Przez lata zamówienie było więc "wpisem" typu shop_order w tabeli wp_posts, a każda jego cecha - adres, kwota, metoda płatności, status, dane dodane przez wtyczki - osobnym wierszem w wp_postmeta. Jedno zamówienie to jeden wiersz w tabeli wpisów i kilkadziesiąt wierszy w tabeli meta.

Przy 50 tysiącach zamówień wp_postmeta ma miliony wierszy, w których obok zamówień siedzą też meta produktów, stron, obrazków i wszystkiego, co jakakolwiek wtyczka kiedykolwiek zapisała. Każde filtrowanie listy zamówień po kliencie, każde wyszukiwanie po adresie e-mail i każdy raport to przeszukiwanie tego worka.

Skutki znasz z panelu: lista zamówień ładuje się sekundy, eksport do pliku kończy się timeoutem, raporty za rok trzeba uruchamiać w nocy. To nie wina WooCommerce, tylko cena za zbudowanie sklepu na fundamencie systemu do blogów. Baza danych to zresztą jedna z przyczyn, które opisałem we wpisie o tym, dlaczego sklep WooCommerce jest wolny.

Co zmienia HPOS - cztery tabele zamiast jednego worka

HPOS przenosi zamówienia do czterech dedykowanych tabel, opisanych w dokumentacji WooCommerce: wp_wc_orders (samo zamówienie), wp_wc_order_addresses (adresy), wp_wc_order_operational_data (dane operacyjne, np. klucz koszyka czy wersja WooCommerce) i wp_wc_orders_meta (metadane z wtyczek). Każda ma własne indeksy zaprojektowane pod zapytania, które sklep faktycznie wykonuje.

Liczby z benchmarku WooCommerce z marca 2023, wykonanego na sklepie testowym z 400 tysiącami zamówień: tworzenie zamówień około 5 razy szybciej, filtrowanie po identyfikatorze klienta do 40 razy szybciej, wyszukiwanie po metadanych około 10 razy szybciej. Te liczby wymagają kontekstu. W sklepie z pięcioma tysiącami zamówień klient w checkoucie nie zauważy różnicy. Zauważy ją obsługa sklepu w panelu i każdy, kto robi raporty, eksporty i integracje z zewnętrznymi systemami. Im więcej zamówień, tym większa różnica.

Równie ważne jest to, czego HPOS nie zmienia. Nie przyspiesza strony produktu ani listingu kategorii, bo produkty nadal siedzą w wp_posts. Nie naprawia złego hostingu i nie zastępuje cache. Jeśli twój sklep jest wolny "od frontu", HPOS nie jest odpowiedzią.

Jedna praktyczna korzyść, o której rzadko się pisze: skoro zamówienia mają własne tabele, kopię samych zamówień da się zrobić i przywrócić bez ruszania reszty bazy.

Tryb zgodności i synchronizacja - skąd biorą się nieporozumienia

Większość problemów z HPOS nie bierze się z samego przełącznika, tylko z tego, co siedzi pod nim. W ustawieniach są w praktyce trzy stany.

Pierwszy: tylko magazyn wpisów, czyli stary sposób. Drugi: tylko HPOS. Trzeci: HPOS z włączonym trybem zgodności (compatibility mode), w którym WooCommerce zapisuje każde zamówienie w obu miejscach naraz. Jedna tabela jest wtedy "autorytatywna" (to z niej sklep czyta), druga jest kopią, do której zmiany są dopisywane.

Tryb zgodności HPOS - stary i nowy magazyn zamówień połączone strumieniem synchronizowanych danych

Tryb zgodności powstał po to, żeby wtyczki czytające zamówienia po staremu (przez get_post_meta albo WP_Query po typie shop_order) działały w okresie przejściowym. Cena jest dwojaka: podwójny zapis przy każdej zmianie zamówienia i ryzyko rozjazdu danych, gdy coś zapisze do niewłaściwej tabeli.

Dwie rzeczy, o które developerzy pytają na forach najczęściej. Po pierwsze: gdy HPOS jest autorytatywny, w wp_posts pojawiają się wpisy typu shop_order_placehold. To nie błąd, tylko rezerwacja numeru zamówienia, żeby żaden inny wpis nie zajął tego samego ID. Po drugie: WooCommerce nie pozwoli przełączyć magazynu, dopóki są zamówienia oczekujące na synchronizację. Komunikat "nie można przełączyć" oznacza zwykle, że trzeba poczekać albo uruchomić synchronizację ręcznie.

Co się stało w WooCommerce 10.7 - sync on read wyłączony

To fragment, którego nie znajdziesz w polskich tekstach o HPOS. Do wersji 10.7 tryb zgodności działał w obie strony. Zapis z HPOS do tabel wpisów (sync on write) to jedna strona. Druga, mniej znana, to sync on read: przy każdym odczycie zamówienia WooCommerce sprawdzał, czy ktoś nie zmienił danych po staremu w wp_postmeta, i jeśli tak, nadpisywał nimi HPOS.

Od WooCommerce 10.7 z 14 kwietnia 2026 sync on read jest domyślnie wyłączony. Sync on write zostaje. W advisory z lutego 2026 WooCommerce uzasadnia to wprost: sync on read pozwalał danym zmienionym poza oficjalnym API nadpisywać aktualne dane w HPOS, co prowadziło między innymi do cofania statusów zamówień.

Kogo to dotyczy? Tylko sklepów, w których jednocześnie zachodzą trzy warunki: HPOS jest włączony, tryb zgodności jest włączony i jakaś wtyczka albo własny snippet zapisuje dane zamówień bezpośrednio do wp_postmeta zamiast przez wc_get_order() i $order->save(). Jeśli którykolwiek warunek nie zachodzi, zmiana cię nie dotyczy.

Jeśli dotyczy, objaw jest podstępny: nic nie pęka. Sklep działa, zamówienia spływają, a dane cicho się rozjeżdżają. Status w panelu inny niż w raporcie, puste pole niestandardowe w zamówieniach z integracji ERP, notatki do zamówień, które "zniknęły". Odkrywasz to miesiąc później, gdy raport przestaje się zgadzać.

Co z tym zrobić: sprawdzić spójność obu magazynów (wp wc hpos verify_data, opis niżej), naprawić kod, który pisze po staremu, i wyłączyć tryb zgodności na stałe. Jako tymczasowy most WooCommerce zostawił filtr:

add_filter( 'woocommerce_hpos_enable_sync_on_read', '__return_true' );

Traktuj go jako czas na naprawę, nie jako rozwiązanie. WooCommerce jasno sygnalizuje kierunek: tryb zgodności był pomostem, a pomosty się rozbiera.

Jak sprawdzić, czy twój sklep jest gotowy

Trzy kroki, od najprostszego.

Lista wtyczek w panelu. WooCommerce → Ustawienia → Zaawansowane → Funkcje, przy polu "Przechowywanie danych zamówień" link "Zobacz i zarządzaj". Ten sam widok dostaniesz pod adresem wp-admin/plugins.php?plugin_status=incompatible_with_feature&feature_id=custom_order_tables. Zobaczysz wtyczki, które nie zadeklarowały zgodności z HPOS.

Brak deklaracji to nie to samo, co niezgodność. Wtyczka na liście może być porzucona (wtedy szukaj zamiennika) albo działać poprawnie i po prostu nie mieć jednej linijki, którą autor powinien dodać. Jeśli piszesz własną wtyczkę albo motyw, ta linijka wygląda tak:

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

W sklepach, którymi się zajmuję, popularne wtyczki z polskiego rynku - kurierzy, faktury, płatności - mają zgodność zadeklarowaną. Problemem są głównie wtyczki, których nikt nie aktualizuje od lat, i własne snippety w functions.php.

Niezgodność działa też w drugą stronę. To rzecz, której nie opisuje nawet dokumentacja WooCommerce, a którą zobaczyłem we własnym panelu na wersji 11.0.1. Przy próbie przełączenia magazynu z HPOS z powrotem na "Magazyn wpisów WordPressa" pojawiło się ostrzeżenie: "Wykryto 1 niezgodną wtyczkę (Flexible Shipping PRO)". Wtyczka może zadeklarować, że wspiera wyłącznie HPOS, i tym samym zablokować powrót do starego magazynu. To legalna decyzja autora, ale ma konsekwencję: włączenie HPOS w sklepie z taką wtyczką jest praktycznie decyzją jednokierunkową. Powrót wymagałby tymczasowego wyłączenia wtyczki od wysyłki, co w działającym sklepie jest osobną decyzją. Wniosek: listę "Zobacz i zarządzaj" sprawdzaj w obu ustawieniach magazynu, nie tylko przed włączeniem HPOS.

Własny kod. W motywie potomnym i własnych wtyczkach szukaj get_post_meta, update_post_meta, wp_insert_post, WP_Query z post_type => 'shop_order' oraz bezpośrednich zapytań $wpdb do wp_posts w kontekście zamówień. Każde z nich ma zamiennik:

Po staremu Zgodnie z HPOS
get_post( $order_id ) wc_get_order( $order_id )
get_post_meta( $order_id, '_klucz', true ) $order->get_meta( '_klucz' )
update_post_meta( $order_id, '_klucz', $val ) $order->update_meta_data( '_klucz', $val ); $order->save();
new WP_Query( [ 'post_type' => 'shop_order' ] ) wc_get_orders( [ ... ] )
$wpdb->get_results( "... FROM wp_posts ..." ) wc_get_orders() albo OrderUtil

Jak przepisać zapytania o zamówienia tak, żeby działały w obu magazynach, opisuję w osobnym wpisie z tej serii.

Jak włączyć HPOS bez utraty zamówień - procedura

Najpierw uczciwe zastrzeżenie: w sklepach, w których włączałem HPOS, przełączenie po prostu zadziałało. To nie jest operacja wysokiego ryzyka. Dane są kopiowane, nie przenoszone, a tabele wpisów zostają na miejscu. Procedura poniżej istnieje nie dlatego, że coś zwykle idzie źle, tylko dlatego, że gdy pójdzie, chcesz mieć drogę powrotu.

Wersja A: mały i średni sklep, przez panel

  1. Pełna kopia bazy danych, z testem odtworzenia na boku. Kopia, której nikt nie odtworzył, jest założeniem, nie backupem.
  2. Kopia sklepu (staging) i cała procedura najpierw na niej. Bez stagingu rób to tylko w sklepie, który może mieć chwilę przestoju poza godzinami zamówień.
  3. W Funkcjach zaznacz "Włącz tryb zgodności". WooCommerce zacznie kopiować zamówienia do tabel HPOS w tle, przez Action Scheduler. Poczekaj, aż licznik zamówień oczekujących spadnie do zera.
  4. Przełącz magazyn na "Wydajne przechowywanie zamówień". Tryb zgodności zostaw włączony na czas testów, tydzień albo dwa.
  5. Testy: złożenie zamówienia, zmiana statusu, zwrot, maile, eksport, wystawienie faktury, nadanie przesyłki, integracje zewnętrzne (ERP, BaseLinker), raporty.
  6. Wyłącz tryb zgodności, gdy wszystko działa. Po zmianie z 10.7 to nie jest krok kosmetyczny, tylko zamknięcie ryzyka rozjazdu danych.

Wersja B: duży sklep, przez WP-CLI

Przy setkach tysięcy zamówień synchronizacja przez Action Scheduler trwa godzinami i obciąża bazę w tle. WooCommerce ma na to zestaw komend WP-CLI i osobny przewodnik dla dużych sklepów. W starszych tekstach spotkasz nazwę wp wc cot - to ten sam zestaw pod poprzednią, wycofaną nazwą.

wp wc hpos status              # czy HPOS i tryb zgodności są włączone, ile zamówień czeka
wp wc hpos count_unmigrated    # tylko liczba zamówień do synchronizacji
wp wc hpos sync                # synchronizacja partiami, szybciej niż przez Action Scheduler
wp wc hpos verify_data         # porównanie wszystkich zamówień w obu magazynach
wp wc hpos diff 100126         # różnice dla jednego zamówienia, czytelna tabela
wp wc hpos backfill 100126 --from=posts --to=hpos --props=status   # naprawa jednego pola
wp wc hpos enable --with-sync  # włączenie HPOS z trybem zgodności
wp wc hpos disable             # powrót do magazynu wpisów (tylko gdy nic nie czeka na sync)
wp wc hpos cleanup all         # usunięcie starych danych z wp_postmeta (destrukcyjne, na końcu)

Kolejność dla dużego sklepu: status, enable --with-sync, sync poza godzinami szczytu, verify_data, testy jak w wersji A, wyłączenie trybu zgodności, i dopiero po tygodniach spokojnej pracy cleanup all, które usuwa metadane zamówień ze starych tabel. Komenda cleanup sama odmówi usunięcia zamówienia, jeśli jego wersja w tabeli wpisów wygląda na nowszą niż w HPOS - to bezpiecznik, nie błąd.

Rollback

Gdy coś nie działa: upewnij się, że tryb zgodności jest włączony, poczekaj na synchronizację (albo uruchom wp wc hpos sync) i przełącz magazyn z powrotem na "Magazyn wpisów WordPressa". Z jednym zastrzeżeniem, o którym pisałem wyżej: jeśli któraś wtyczka wspiera wyłącznie HPOS, panel zablokuje powrót, dopóki jej nie wyłączysz.

Kiedy NIE włączać HPOS (albo jeszcze nie)

Każdy tekst w tej serii ma taką sekcję, bo bez niej byłby instrukcją, a nie odpowiedzią.

Włączenie HPOS w WooCommerce - przełącznik na panelu z czterema kontrolkami, z których jedna jeszcze nie świeci

Nie włączaj HPOS, gdy krytyczna dla sprzedaży wtyczka - płatności, kurier, faktury, integracja z ERP - jest na liście bez zgodności, a jej autor nie odpowiada. Najpierw zamiennik, potem HPOS.

Poczekaj, gdy w sklepie jest własny kod, którego nikt nie zna, na przykład po przejęciu sklepu po innym developerze. Ostrożna migracja, którą opisałem przy przebudowie sklepu bez utraty SEO i historii zamówień, zaczyna się od zrozumienia, co w sklepie siedzi, a nie od przełączników.

Poczekaj, gdy nie masz stagingu ani backupu z testem odtworzenia. Włączenie HPOS nie jest ryzykowne samo w sobie, ale nie ma sensu robić go na ślepo.

Możesz spokojnie poczekać, gdy sklep ma kilkaset zamówień rocznie, wszystko działa i nikt nie narzeka na panel. Zysk jest realny, ale mały. Naturalny moment przyjdzie sam: większa aktualizacja, zmiana motywu, przebudowa.

I nie rób tego w tygodniu przed Black Friday ani w środku wyprzedaży.

"Jeszcze nie" to nie "nigdy". WooCommerce jasno pokazuje kierunek, każda nowa instalacja startuje na HPOS, a zmiana z 10.7 mówi wprost, że okres przejściowy się kończy.

Podsumowanie

HPOS nie jest eksperymentem, tylko docelowym sposobem przechowywania zamówień w WooCommerce. Ryzyko nie leży w przełączniku, tylko w kodzie, który pisze do zamówień po staremu - i w wtyczkach, które po włączeniu HPOS nie pozwolą ci wrócić. Po wersji 10.7 tryb zgodności to pomost do rozebrania, nie ustawienie, o którym można zapomnieć.

Jeśli nie chcesz sam przechodzić przez listę wtyczek i własnego kodu, umów bezpłatną konsultację. Sprawdzimy, czy sklep jest gotowy i co trzeba poprawić przed przełączeniem.

FAQ

HPOS (High-Performance Order Storage) to sposób przechowywania zamówień w czterech dedykowanych tabelach bazy danych zamiast w ogólnych tabelach wpisów WordPressa. W polskim panelu nazywa się "Wydajne przechowywanie zamówień". Daje szybsze wyszukiwanie, filtrowanie i raportowanie zamówień, szczególnie w sklepach z dużą ich liczbą.

Od WooCommerce 8.2 (październik 2023) tak, ale tylko w nowych instalacjach. Sklep uruchomiony wcześniej zostaje na magazynie wpisów WordPressa, dopóki ktoś świadomie nie przełączy go w ustawieniach.

Nie. Dane są kopiowane do nowych tabel, a tabele wpisów zostają nietknięte, dopóki nie uruchomisz świadomie komendy czyszczącej. Realne ryzyko to nie utrata, tylko rozjazd danych między magazynami, gdy jakaś wtyczka albo snippet zapisuje zamówienia po staremu.

Tryb zgodności (compatibility mode) sprawia, że WooCommerce zapisuje każde zamówienie jednocześnie w tabelach HPOS i w tabelach wpisów. Powstał na okres przejściowy, żeby starsze wtyczki nadal działały. Kosztuje podwójny zapis i po testach powinien zostać wyłączony.

Od wersji 10.7 (kwiecień 2026) tryb zgodności nie nadpisuje już danych HPOS zmianami wprowadzonymi po staremu w tabelach wpisów (sync on read). Dotyczy to tylko sklepów z włączonym HPOS, włączonym trybem zgodności i kodem piszącym bezpośrednio do wp_postmeta. Tymczasowo można przywrócić stare zachowanie filtrem woocommerce_hpos_enable_sync_on_read.

W panelu WooCommerce, Ustawienia, Zaawansowane, Funkcje, przy polu przechowywania zamówień kliknij "Zobacz i zarządzaj". Zobaczysz wtyczki bez zadeklarowanej zgodności. Brak deklaracji nie zawsze oznacza, że wtyczka nie działa, ale oznacza, że nikt tego nie potwierdził.

Niektóre wtyczki, na przykład Flexible Shipping PRO, deklarują wsparcie wyłącznie dla HPOS i blokują powrót do magazynu wpisów WordPressa. Żeby wrócić, trzeba taką wtyczkę tymczasowo wyłączyć albo zostać przy HPOS. Dlatego listę niezgodnych wtyczek warto sprawdzić w obu ustawieniach magazynu przed przełączeniem.

Panel zamówień, wyszukiwanie, raporty i eksporty tak, mierzalnie przy tysiącach zamówień. Strony produktów i kategorii nie, bo produkty nadal są przechowywane w tabelach wpisów. HPOS nie zastępuje też dobrego hostingu ani cache.

Wróć do bloga

Chcesz zacząć projekt?

Porozmawiajmy

Napisz do mnie

Administratorem danych jest Marcin Siemieniuk-Morawski. Dane z formularza służą wyłącznie do odpowiedzi na Twoją wiadomość. Szczegóły w polityce prywatności.

Możesz też napisać bezpośrednio na: kontakt@ms-m.pl