Przed/po: migracja na nowe CMS — efekty po 12 tygodniach i kluczowe wnioski

Migracja CMS to jedna z tych decyzji, które potrafią albo pchnąć serwis o kilka lat do przodu, albo cofnąć go do punktu wyjścia. Nie ma tu drogi pośredniej — albo robi się ją jako inwestycję w przyszłość (szybkość, elastyczność, obsługa AI Overviews, wdrożenie danych strukturalnych), albo łata się tylko to, co boli dziś. W tym artykule opisujemy konkretny przypadek: średniej wielkości serwis branżowy, który przez lata stał na Drupalu 7 i w końcu musiał się ruszyć. Dlaczego? Bo koszt bezczynności zaczął przewyższać koszt zmiany — każdy kolejny miesiąc oznaczał wolniejsze strony, więcej duplikatów, rosnący udział soft 404 i coraz większą trudność w wypychaniu nowych treści z redakcji do produkcji.

Poniżej znajdziesz twarde liczby przed i po 12 tygodniach od uruchomienia nowej architektury (WordPress + warstwa headless dla sekcji katalogowych), plan migracji krok po kroku, błędy których nie chcesz powtórzyć oraz framework, którym posługujemy się wewnętrznie przy każdym projekcie tego typu. Case jest zanonimizowany i uproszczony — ale liczby, sekwencja działań i wnioski pochodzą z realnego projektu. Jeśli stoisz przed decyzją „zmieniać czy nie zmieniać” — to case dla Ciebie.

Stare CMS: dlaczego Drupal 7 przestał się bronić

Zanim przejdziemy do liczb, kilka słów o punkcie wyjścia. Mówimy o serwisie z około 2 400 opublikowanymi wpisami, katalogiem produktowym liczącym ponad 6 000 wpisów, trzema sekcjami językowymi (PL, EN, DE) i średnim miesięcznym ruchem organicznym rzędu 180 000 sesji. Serwis działał na Drupalu 7 od 2014 roku. Co poszło nie tak? Nie jedna rzecz — raczej lawina drobnych zaniedbań, która w którymś momencie przestała być do udźwignięcia.

Performance: TTFB powyżej 1,2 s i LCP w okolicach 4 s

Pierwszy problem był najbardziej widoczny dla użytkownika i najbardziej mierzalny dla Google. Serwer aplikacyjny robił po kilkanaście zapytań SQL przed wygenerowaniem pierwszego bajtu HTML, cache był inwalidowany zbyt agresywnie (każda edycja wpisu czyściła cały region katalogu), a obrazy trafiały na stronę w oryginalnych rozdzielczościach 3000 px bez lazy loadingu. W konsekwencji LCP (Largest Contentful Paint) na urządzeniach mobilnych oscylował wokół 3,8–4,2 s, a INP (Interaction to Next Paint) regularnie przebijał 380 ms. Core Web Vitals w Search Console świeciły się na czerwono od miesięcy i nikt już nie patrzył na ten raport, bo „i tak się nie da tego naprawić”.

Duplikaty i kanibalizacja

Drupal 7 generował dziesiątki wariantów URL dla jednego materiału: z parametrami sortowania, filtrowania, paginacji, wersjami drukowalnymi oraz starymi aliasami, które nigdy nie zostały usunięte. W efekcie jeden artykuł miał średnio 4–6 adresów, z których każdy był częściowo indeksowany, częściowo kanonizowany, a częściowo wyrzucany do „Wykryte, obecnie niezaindeksowane”. Audyt wykazał ponad 18 000 adresów z treścią zduplikowaną i około 7 400 adresów konkurujących o te same zapytania.

Redakcja uciekała do Notiona

To brzmi jak żart, ale nie jest. Panel edycyjny Drupala 7 wymagał tylu kliknięć i tyle razy się rozsypywał przy wklejaniu treści z Google Docs, że redaktorzy pisali w Notionie, a do CMS-a wchodzili tylko na ostatnim kroku. Konsekwencja: rozjazd między „prawdziwym” tekstem a tym, co widział Googlebot, brak spójnej struktury nagłówków, brak alt tekstów w obrazach wklejanych z pośpiechu, nieobecne meta description w 60% nowych publikacji.

Bezpieczeństwo i koniec wsparcia

Drupal 7 osiągnął End of Life — i to był ostatni gwóźdź. Utrzymywanie core’a na własnych łatkach kosztowało coraz więcej, zewnętrzne moduły przestawały otrzymywać aktualizacje, a audyt bezpieczeństwa wykazał sześć krytycznych podatności, z czego dwie bez łatki. Dalsze siedzenie na tej wersji zaczynało być ryzykiem biznesowym, nie tylko technicznym.

Koszt ukryty: zespół deweloperski zamiast redakcji

Jest jeszcze jeden koszt, o którym rzadko się mówi, bo trudno go zmierzyć w arkuszu. Zespół techniczny spędzał tygodniowo około 12 godzin na samym utrzymaniu Drupala 7 — łatanie, monitorowanie modułów, interwencje po wdrożeniach. To jest czas, którego nie spędza się na rozwoju produktu, nie spędza się na supportowaniu redakcji, nie spędza się na integracjach z nowymi narzędziami. W skali roku to 600 godzin — pół etatu programisty. Przy stawkach rynkowych 2026 roku to około 120 000 zł kosztu operacyjnego, który nie generuje wartości, a tylko utrzymuje status quo. Policzyliśmy to przed kick-offem projektu migracji i liczba była jednym z argumentów, który przekonał zarząd.

Wybór nowego CMS: kryteria i decyzja

Wbrew pozorom, wybór „na co migrujemy” nie był oczywisty. Na stole leżały cztery opcje: Drupal 10 (czyli pozostanie w rodzinie, ale z pełnym przepisaniem), Sanity + Next.js (pełny headless), Statamic (Laravel-based, z wygodnym edytorem), oraz WordPress z custom frontendem. Zespół miał dwa wymagania, które okazały się decydujące: redakcja musi pokochać panel i musimy móc zatrudnić developera w tydzień, a nie w trzy miesiące. To automatycznie wykluczyło Sanity i Statamica — oba są świetne, ale rynek specjalistów w Polsce jest za wąski.

Dlaczego WordPress + headless zamiast czystego WordPressa?

Padło pytanie: dlaczego nie klasyczny WordPress z szablonem PHP? Odpowiedź leżała w architekturze treści. Serwis miał dwie bardzo różne sekcje: blog (prosta, linearna, idealna dla klasycznego WP) oraz katalog produktów z filtrowaniem, porównywarkami, interaktywnymi tabelami i integracjami z danymi zewnętrznymi. Dla katalogu klasyczny frontend PHP byłby ciężki, trudny do cache’owania i niemożliwy do obsłużenia z poziomu CDN brzegowego.

Rozwiązanie kompromisowe: WordPress jako headless CMS (treści, użytkownicy, role, media, SEO) dla katalogu, plus klasyczny motyw dla bloga i landing page’ów. Frontend katalogu napisany w Next.js, hostowany na edge, z ISR (Incremental Static Regeneration) dla list i SSG dla kart produktowych. Blog i strony statyczne pozostają w WordPressie, bo tam nie ma sensu komplikować.

Wtyczki, które wchodzą do zestawu

Przy WordPressie problemem nie jest to, że się nie da — tylko to, że da się zbyt wielu drogami. Trzeba wybrać dyscyplinę. Finalny stack: Rank Math (SEO), ACF (struktury pól dla katalogu), WP All Import (jednorazowa migracja), WP Rocket (cache), Redis Object Cache (obiektowy cache), Blogers Connector (headless API + publishing). Żadnych page builderów. Edycja treści w blokach Gutenberga z własnymi blokami dla elementów powtarzalnych. Jeśli zajmujesz się SEO na WordPressie, warto też zerknąć na nasz przewodnik Core Web Vitals w 2026, bo optymalizacja wtyczek to oddzielna warstwa pracy, która potrafi zjeść 20–30% poprawy albo ją zniweczyć.

Co odrzuciliśmy i dlaczego

Dla porządku: Drupal 10 byłby najszybszy do migracji technicznie, ale nie rozwiązywał problemu z redakcją — panel Drupala 10 jest lepszy od siódemki, ale wciąż ciężki dla redaktorów przyzwyczajonych do Notiona i Google Docs. Sanity dawałoby najbardziej elastyczny model treści, ale zespół developerski musiałby przejść szkolenie z GROQ (język zapytań Sanity), a rekrutacja nowego developera oznaczała minimum dwa miesiące onboardingu. Statamic wypadł dobrze w porównaniu, ale licencjonowanie per-site i brak szerokiej społeczności polskich wtyczek SEO były dyskwalifikujące dla projektu, który ma działać kolejne 6–8 lat bez refaktoru.

Plan migracji: co robimy, a czego nie robimy w tym samym czasie

Migracja jest projektem, w którym więcej szkód robi chaos niż opóźnienie. Dlatego pierwszą decyzją było: nie robimy zmian w strukturze treści i URL równolegle z redesignem. To były dwa osobne etapy. Etap 1 — migracja techniczna z zachowaniem URL i struktury; etap 2 — redesign i porządkowanie taksonomii. Gdybyśmy próbowali zrobić wszystko razem, ryzyko regresji w ruchu byłoby ogromne, a debugging — niemożliwy.

Audyt stanu zero

Zanim ktokolwiek dotknął kodu, powstał dokument „stan zero” — pełna lista URL-i z Search Console i własnych crawlerów, kluczowe strony rankingowe, top wpisy pod ruchem, wszystkie 301 i 302 aktualnie działające, mapowanie kategorii, lista pól niestandardowych w Drupalu. Bez tego migracja to strzelanie w ciemno. Na tym etapie wyłapaliśmy 214 starych przekierowań, które w nowej architekturze trzeba było zreplikować co do znaku.

Środowisko staging z produkcyjnymi danymi

Staging nie może być „podobny do produkcji” — musi być identyczny, z rzeczywistymi danymi, rzeczywistymi obrazami i rzeczywistym ruchem testowym. Zbudowaliśmy środowisko z klonem bazy danych, podpięliśmy CDN na subdomenie staging.* i uruchomiliśmy syntetyczny ruch testowy przez 10 dni przed premierą, żeby wyłapać wycieki pamięci, problemy z cache i zachowanie pod obciążeniem.

Mapowanie URL 1:1

Reguła nr 1: żaden adres nie znika bez przekierowania 301 na najbliższy sensowny odpowiednik. Nie na stronę główną, nie na kategorię — na konkretny dokument. Przygotowaliśmy arkusz z 8 900 wierszami mapującymi stare URL-e na nowe. Wszystkie kategorie kończące się na ukośniku pozostały z ukośnikiem. Wszystkie artykuły bez rozszerzenia zachowały swoją formę. Paginacje zostały zastąpione parametrem page, stare filtry — które i tak były indeksowane błędnie — zostały zablokowane w robots.txt i wyłączone z generowania linków. Dokładnie takie podejście opisujemy w poradniku przekierowań 301 przy migracji, który powstał właśnie po tym projekcie.

Harmonogram tygodniowy

Projekt trwał 14 tygodni od kick-offu do premiery, a dodatkowe 12 tygodni obserwacji to właśnie okres, po którym mierzyliśmy wyniki w tym artykule. Harmonogram w grubych blokach: tygodnie 1–2 audyt i architektura, 3–6 development core’u i skryptów migracyjnych, 7–8 migracja próbna i QA, 9–10 testy obciążeniowe i hardening, 11–12 migracja z danymi, UAT, 13 freeze, 14 premiera nocą z piątku na sobotę. Wybór weekendu nie był przypadkowy — typowy ruch w sobotę rano to 40% dnia roboczego, więc ewentualny downtime kosztował najmniej.

Role i odpowiedzialności — kto za co odpowiada

Projekt tej skali wymaga jasnego podziału ról, bo jeśli każdy odpowiada za wszystko, to nie odpowiada nikt. W naszym przypadku podział wyglądał tak: Tech Lead — architektura, decyzje technologiczne, code review, eskalacje; SEO Lead — mapowanie URL, struktura danych, komunikacja ze Search Console, decyzje o canonical i noindex; Content Lead — freeze contentu, szkolenie redakcji, QA tekstów po migracji; DevOps — infrastruktura, staging, CDN, load balancer, rollback plan; Project Manager — harmonogram, ryzyka, komunikacja do zarządu, spotkania statusowe. Pięć osób w core teamie, plus 2–3 developerów wspierających. Mniej niż pięć ról to ryzyko, że któraś odpowiedzialność spadnie między biurka; więcej — to zbyt dużo narzuconego narzutu komunikacyjnego.

Execution: weekend premierowy i pierwsze 72 godziny

Premiera zaczęła się o 22:00 w piątek. Kolejność była następująca: zamrożenie edycji w starym CMS-ie, ostatni pełny dump bazy, import do nowego środowiska, weryfikacja 50 losowych URL-i, przełączenie DNS na nowy IP, weryfikacja TLS, ponowna indeksacja przez URL Inspection dla 30 kluczowych stron, ping sitemapy. O 2:00 w nocy wszystko świeciło się na zielono. Pierwszy realny test to był poranek sobotni — i tu zaczęły się ciekawostki.

Co się wydarzyło w sobotę rano

Googlebot wszedł ostro — w ciągu pierwszych 6 godzin od zmiany DNS zaindeksował ponad 4 000 nowych URL-i. Tylko że jednocześnie zaczął pukać do starych, jeszcze w wersji z parametrami. Nasze 301 działały poprawnie, ale load balancer w pierwszych godzinach nie cachował odpowiedzi 301 — każde przekierowanie generowało request do aplikacji. To dało szczyt 3 200 req/s i trzeba było w trybie awaryjnym przenieść logikę 301 na poziom edge (Cloudflare Workers). Po tej zmianie czas odpowiedzi dla przekierowań spadł z 180 ms do 8 ms, a load na backendzie wrócił do normy.

Pierwsze błędy redakcyjne

W niedzielę rano okazało się, że redaktorzy nie rozumieją, że w nowym panelu istnieją dwa różne typy wpisów: „Artykuł bloga” i „Karta produktu”. Pierwsze dwa teksty wylądowały w złym miejscu — i wylądowały jako nowe URL-e, bo Gutenberg nie miał włączonej ochrony slugów. To kosztowało kolejne dwa 301 w stosie i krótki szkoleniowy call w poniedziałek rano. Wniosek na przyszłość: szkolenie redakcji przed migracją, nie po.

Dzień trzeci: wycieki w cache

Poniedziałkowy poranek przyniósł kolejny problem — powolną degradację czasu odpowiedzi. O 9:00 TTFB wynosił 180 ms, o 12:00 — 420 ms, o 15:00 — 780 ms. Okazało się, że Redis Object Cache był skonfigurowany z limitem pamięci 2 GB, a strategia eviction była ustawiona na noeviction. Po kilku godzinach cache się zapełnił, nowe zapisy zaczęły wracać błędami, WordPress przechodził na tryb bez cache’a obiektowego i każde żądanie odpalało od zera. Zmiana strategii na allkeys-lru i podniesienie limitu do 4 GB rozwiązało problem w 10 minut. Ale to był sygnał ostrzegawczy: w tygodniu po migracji trzeba monitorować każdą metrykę z podwójną uwagą, bo konfiguracje, które działały na staging, mogą zachowywać się inaczej pod realnym ruchem.

Rezultaty po 12 tygodniach: twarde liczby

Przez pierwsze dwa tygodnie po migracji ruch organiczny spadł o około 18% — co było spodziewane, bo Google musi zaindeksować nowe URL-e i skonsolidować sygnały. Od trzeciego tygodnia widzieliśmy stabilny trend wzrostowy. Poniższa tabela pokazuje kluczowe wskaźniki przed migracją (średnia z 4 tygodni bazowych) i po 12 tygodniach od premiery.

Wskaźnik Przed Po 12 tyg. Zmiana
LCP mobile (p75) 3,9 s 1,6 s -59%
INP mobile (p75) 380 ms 140 ms -63%
CLS mobile (p75) 0,18 0,04 -78%
TTFB średni 1 240 ms 210 ms -83%
Strony z „Dobry” w CWV 11% 87% +76 pp
Crawl budget / dzień 28 400 61 900 +118%
URL-e zaindeksowane 14 700 9 850 -33%
URL-e „Wykryte, nie zaindeksowane” 18 200 2 400 -87%
Soft 404 1 840 38 -98%
Ruch organiczny (sesje/mies.) 180 000 247 000 +37%
Ruch do top 10 stron rankingowych 62 000 104 000 +68%
Cytowania w AI Overviews nie mierzone 14/mies. n/d
Czas publikacji wpisu (redakcja) 22 min 7 min -68%

Zwróć uwagę na jedną pozornie dziwną liczbę: spadek liczby URL-i zaindeksowanych o 33%. To nie jest regresja — to konsolidacja. Przed migracją indeksowane były dziesiątki wariantów tego samego dokumentu; po migracji Google widzi jedną kanoniczną wersję. Efekt? Ten sam ruch trafia do mniejszej liczby lepszych stron, a to przekłada się na wzrost mocy pojedynczej publikacji. Jeśli interesuje Cię szersza analiza tego zjawiska, zerknij do naszego case study konsolidacji duplikatów, gdzie pokazujemy podobne efekty na trzech różnych serwisach.

Co zobaczyliśmy w Search Console

Oprócz samych liczb, kilka obserwacji jakościowych. Po pierwsze: Google Discover wrócił jako realny kanał ruchu — przed migracją mieliśmy dosłownie okazjonalne wyświetlenia, po migracji stabilne 8–15 tys. sesji miesięcznie. Po drugie: średnia pozycja fraz long tail spadła (w sensie poprawiła się) o około 4 pozycje — z 18,2 na 14,1. Po trzecie: liczba fraz w top 3 wzrosła o 124%, głównie dzięki temu, że frazy, które wcześniej dzieliły się między kilka duplikatów, skonsolidowały się na jednym dokumencie.

Ruch, który przyszedł z nieoczekiwanego miejsca

Jedna z najbardziej zaskakujących obserwacji — w tygodniach 9–12 zaczął rosnąć ruch z wyszukiwania obrazów (Google Images). Przed migracją ten kanał dawał nam około 3 500 sesji miesięcznie, po — 14 200. Powód? W starym CMS-ie obrazy były serwowane w oryginalnych rozdzielczościach bez nowoczesnych formatów (WebP, AVIF), bez atrybutów loading i z błędnymi alt tekstami dla części zasobów. W nowej architekturze pipeline obrazów automatycznie generuje cztery warianty (320, 640, 1024, 1920 px) w WebP i AVIF, a atrybuty alt są wymagane przez szablon (pole ACF z walidacją). To nie była zaplanowana optymalizacja, ale efekt uboczny porządkowania — i jeden z największych źródeł nieoczekiwanego wzrostu ruchu.

Zmiana wzorca konwersji

Dla zespołu produktowego najciekawszy wynik to zmiana zachowania użytkownika. Średni czas na stronie wzrósł z 2:14 do 3:08 (+40%), a bounce rate spadł z 64% do 48%. To nie są wskaźniki, które Google bezpośrednio używa jako sygnału rankingu, ale są silnym wskaźnikiem jakości ruchu — i przekładają się na mierzalne efekty biznesowe. Współczynnik zapisów do newslettera wzrósł z 1,2% do 2,1%, a liczba leadów B2B z formularza kontaktowego — z 120 do 198 miesięcznie. Hipoteza: szybsza strona i lepsze linkowanie wewnętrzne dają użytkownikowi więcej kliknięć w trakcie jednej sesji, co zwiększa ekspozycję na call-to-action w różnych miejscach serwisu.

Framework migracji w 8 krokach

Przed rozpisaniem frameworka, jedno zastrzeżenie: to nie jest checklista do mechanicznego odhaczenia. Każdy krok wymaga kilku dni, czasem tygodnia. Jeśli któryś próbujesz przeskoczyć — zapłacisz za to na etapie premiery.

  1. Audyt stanu zero. Eksport wszystkich URL-i z GSC, Ahrefs/Semrush, własnego crawlera. Lista top 200 stron pod ruchem, top 200 pod linkami, top 200 pod konwersjami. Lista 301 i 302 w aktualnym systemie. Mapowanie pól niestandardowych. Bez tego kroku nie ruszasz.
  2. Decyzja o architekturze. Monolit, headless, hybryda. Decyzja powinna być prowadzona przez dwa pytania: jakie masz typy treści i kto będzie je edytował. Technologia dopasowuje się do odpowiedzi, nie odwrotnie.
  3. Mapowanie URL 1:1. Arkusz: stary URL → nowy URL → typ (301, 302, canonical, no-action). Żadnego URL-a nie można zostawić bez decyzji. Jeśli nie wiesz, co zrobić — to znaczy, że nie zrobiłeś kroku 1 do końca.
  4. Skrypty migracyjne z testami. Import do staging nie jest jednorazowy — zbuduj go tak, żeby móc uruchomić go 20 razy. Dodaj testy: liczba wpisów, liczba obrazów, liczba relacji kategoria → wpis. Każde uruchomienie porównuje się z poprzednim.
  5. Staging z produkcyjnymi danymi i CDN-em. Ten krok najczęściej jest skracany — i najczęściej mści się potem. Bez realnego ruchu i realnego CDN-u nie wiesz, jak zachowa się premiera.
  6. Hardening i testy obciążeniowe. Syntetyczny ruch przez 5–10 dni na staging, z profilami zbliżonymi do produkcji. Cel: znaleźć wąskie gardła, zanim znajdzie je Googlebot w sobotę rano.
  7. Premiera w oknie niskiego ruchu. Noc z piątku na sobotę albo z soboty na niedzielę. Zawsze z planem rollbacku przygotowanym do minuty.
  8. Monitoring 30 dni i szybkie iteracje. Pierwsze 30 dni to nie czas na nowe funkcje. To czas na obserwację, poprawki, szybkie reakcje na to, co odkrywa Googlebot. Codzienny raport z GSC, Core Web Vitals, logów serwera i ruchu organicznego.

Ten framework wynika z błędów — własnych i cudzych. Każdy z ośmiu kroków ma za sobą co najmniej jeden projekt, w którym jego pominięcie kosztowało dwucyfrowy procent ruchu.

Najczęstsze błędy podczas migracji CMS

Jeśli miałbym wskazać błędy, które widzę najczęściej — i które widziałem też u siebie, zanim nauczyłem się ich unikać — wyglądają mniej więcej tak.

Błąd 1: zmiana URL-i „bo nowe są ładniejsze”

Klasyk. Nowy CMS oferuje inną strukturę slugów, zespół uważa, że „/blog/kategoria/nazwa-wpisu” wygląda lepiej niż „/kategoria/nazwa-wpisu”. Efekt: 8 000 przekierowań 301, częściowa utrata mocy linków, spadek ruchu na 3–6 tygodni. Jeśli zmieniasz URL-e, rób to z konkretnym, biznesowym powodem — nie estetycznym.

Błąd 2: brak testu 301 przed premierą

Plik z przekierowaniami istnieje, ale nikt go nie uruchomił przeciw rzeczywistej liście URL-i z ostatnich 12 miesięcy. W dniu premiery okazuje się, że 400 przekierowań się nie uruchamia, bo regex był zły. Prostsze niż się wydaje do uniknięcia — jeden skrypt w godzinę.

Błąd 3: obrazy bez atrybutów i w oryginalnej rozdzielczości

Import treści bierze HTML „as-is” i przenosi obrazy 4000 px na nowy CMS. Nowa architektura ich nie kompresuje automatycznie, bo wrzucone są z oznaczeniem „migracja” i wyłączone z pipeline. Wynik: LCP wyższy o 1,5 s po premierze niż na staging. Zawsze uruchamiaj pipeline obrazów również na zaimportowanej treści.

Błąd 4: brak komunikacji z redakcją

Nowy panel, nowy workflow, nowe pola — i redakcja dowiaduje się o tym w poniedziałek rano. Pierwszy dzień po premierze to cisza publikacyjna, drugi dzień to błędne publikacje, trzeci to formalne pismo od redakcji do zarządu. Szkol tydzień przed premierą, nie dzień po.

Błąd 5: „sitemap wyślemy potem”

Nowa sitemapa XML powinna być wygenerowana i wysłana do GSC w pierwszych 2 godzinach po premierze. „Potem” oznacza 3 dni, w których Googlebot nie wie, co się właściwie dzieje, i zaczyna mapować strukturę po omacku. W najgorszym przypadku indeksuje stare URL-e przekierowane.

Błąd 6: ignorowanie logów serwera

Core Web Vitals to jedna perspektywa, ale logi serwera — druga. W pierwszych 7 dniach po premierze codziennie analizuj logi: jakie URL-e odwiedza Googlebot, ile czasu zajmuje odpowiedź, jaki procent 4xx i 5xx. Tam ukrywają się problemy, których GSC nie pokaże przez 2 tygodnie.

Błąd 7: freeze contentu, o którym nikt nie wie

Ostatni tydzień przed premierą to freeze — żadnych nowych publikacji, żadnych edycji. Ale jeśli freeze nie jest skomunikowany i nie jest wyegzekwowany na poziomie ról w CMS-ie, to zawsze znajdzie się redaktor, który „szybko wrzuci ten jeden wpis, bo kampania”. I tego wpisu nie będzie w nowym systemie, bo migracja wzięła dump z wtorku.

Błąd 8: brak planu rollbacku z konkretnymi krokami

„Jak coś pójdzie nie tak, to cofniemy” — to nie jest plan rollbacku. To pobożne życzenie. Realny plan rollbacku zawiera: dokładną procedurę powrotu DNS, lokalizację i datę ostatniego dumpu starej bazy, listę osób z uprawnieniami do wykonania rollbacku, decyzyjne kryteria („kiedy rollujemy back, a kiedy walczymy dalej”), okno czasowe, po którym rollback staje się niemożliwy (zwykle 24–48 h po premierze, bo nowe publikacje w nowym CMS-ie nie przejdą do starego). Pisemny, przetestowany, zaakceptowany przez zarząd przed premierą.

Błąd 9: brak monitoringu 404 po premierze

W pierwszym tygodniu po migracji codziennie pojawi się kilkadziesiąt nowych 404. Część z nich to stare URL-e pominięte w mapowaniu, część to błędne linki wewnętrzne, część to zewnętrzne odwołania, o których nie wiedzieliście. Bez aktywnego monitoringu (codzienny raport z logów + narzędzie typu Little Warden albo własny skrypt na GSC API) ten ogon wzrasta i po miesiącu masz 2 000 martwych linków, których nikt nie naprawi.

FAQ: najczęstsze pytania o migrację CMS

Czy migracja CMS zawsze wiąże się ze spadkiem ruchu?

W krótkim okresie (2–6 tygodni) zwykle tak — Google musi zaindeksować nowe URL-e i skonsolidować sygnały. W średnim okresie (3–6 miesięcy) dobrze przeprowadzona migracja przynosi wzrost, zwłaszcza jeśli adresuje problemy z duplikatami i performance. Źle przeprowadzona potrafi obniżyć ruch trwale.

Ile trwa realna migracja średniego serwisu?

Dla serwisu rzędu 2–10 tys. wpisów realistyczny harmonogram to 10–16 tygodni od audytu do premiery, plus 30–60 dni stabilizacji. Krótsze terminy są możliwe, ale zwykle kosztem jakości jednego z kroków frameworku.

Czy warto zmieniać URL-e przy okazji migracji?

Tylko jeśli jest twardy biznesowy powód. Każdy zmieniony URL to przekierowanie, każde przekierowanie to utrata części mocy linków, ryzyko błędu i dodatkowy koszt monitoringu. Domyślna odpowiedź: nie, zachowujemy URL-e. Wyjątki: taksonomia jest tak popsuta, że i tak wymaga restrukturyzacji.

WordPress czy headless?

Zależy od typu treści i zespołu. Blog + strony statyczne → klasyczny WordPress. Katalog + aplikacja + treści interaktywne → headless (WP + Next.js albo inny framework). Hybryda często ma sens — to właśnie wybraliśmy w opisanym case’ie.

Czy Google karze za 301?

Nie w sensie algorytmicznym. Ale duża liczba 301 (kilkadziesiąt tysięcy jednorazowo) to sygnał dla Google’a, że struktura serwisu się zmieniła — i to uruchamia proces ponownej oceny, który trwa tygodnie. Minimalizuj liczbę 301, trzymaj łańcuchy krótkie (max 1 skok), monitoruj 301 przez co najmniej 6 miesięcy po premierze.

Jak długo trzymać stare URL-e z 301?

Oficjalnie Google traktuje 301 jako permanentne. Praktycznie: trzymaj co najmniej 12 miesięcy, a dla top stron — na zawsze. Koszt utrzymania reguły przekierowania jest minimalny, koszt jej usunięcia i utraty ruchu — wysoki.

Czy migracja wpływa na AI Overviews?

Tak, w obie strony. Jeśli migracja poprawia strukturę danych, schema.org, semantyczną czystość dokumentów — cytowania w AI Overviews rosną (w naszym case 0 → 14 cytowań/mies.). Jeśli migracja psuje strukturę lub zmienia URL-e cytowanych dokumentów bez 301 — cytowania spadają.

Czy migrację da się zrobić bez downtime?

Tak, blue-green deployment z przełączeniem DNS pozwala na zero downtime dla użytkownika. Ale okienko 30–60 minut niedostępności panelu redakcyjnego jest praktycznie nieunikniene. Oficjalna dokumentacja WordPressa zawiera szczegółowe wskazówki dla scenariuszy multisite, a Drupal udostępnia oficjalny przewodnik migracji z Drupala 7, który warto przejść, nawet jeśli finalnie migrujesz poza Drupala.

Co dalej: życie po migracji

Premiera to nie koniec projektu — to początek fazy, w której widać, czy wszystkie założenia były trafne. Pierwsze 30 dni po premierze poświęcasz na obserwację i drobne korekty. Kolejne 60 dni — na optymalizację: dostrajanie cache, poprawki Core Web Vitals dla szczegółowych typów stron (kategorie zachowują się inaczej niż karty produktowe, a te inaczej niż wpisy bloga), audyt struktury linków wewnętrznych, która w nowym CMS-ie zwykle wymaga przemyślenia na nowo.

Kolejny etap to treść. Nowa architektura oznacza, że możesz wreszcie robić rzeczy, które w starym CMS-ie były technicznie niemożliwe albo zbyt kosztowne — tabele porównawcze z żywymi danymi, dynamiczne podsumowania, bloki FAQ z automatycznym schema.org, personalizacja kontentu pod źródło ruchu. To jest moment, w którym inwestycja w migrację zaczyna się zwracać z procentem składanym, bo każda nowa publikacja trafia w lepszy ekosystem techniczny.

Warto też spojrzeć na migrację jako na reset długu technicznego, ale nie jako na jego eliminację. Dług narasta od dnia premiery — w postaci nowych wtyczek, nowych pól ACF, nowych integracji, nowych redaktorów z własnymi preferencjami. Planowy przegląd kwartalny (co trzy miesiące: co dodaliśmy, co usuwamy, co upraszczamy) to jedyna znana mi metoda, żeby za pięć lat nie wrócić do punktu wyjścia z Drupalem 7. Bo wtedy znowu trzeba będzie migrować — a migracja, jak wiesz już po przeczytaniu tego tekstu, jest kosztownym sportem.

Jest jeszcze jeden wymiar, o którym rzadko się mówi: migracja zmienia relację między zespołem technicznym a redakcją. Przed migracją redakcja traktowała techników jako blokerów („nie da się dodać tabeli”, „znowu nie działa wstawianie obrazków”). Po migracji, jeśli została dobrze przeprowadzona, te rozmowy znikają — i w ich miejsce pojawiają się rozmowy o treści, dystrybucji, strategii. To jest moment, w którym zespół content zaczyna pytać: „skoro panel działa, skoro publikacja zajmuje 7 minut, skoro mamy dwa razy większy ruch — co powinniśmy zacząć pisać?”. I to jest właściwa rozmowa, której nie mieliśmy przez trzy lata. Warto doceniać ten pozornie nieuchwytny efekt, bo długoterminowo on przekłada się na jakość contentu — a jakość contentu jest dziś jednym z niewielu sygnałów, których Google i modele językowe nie potrafią udawać.

Jeśli jesteś w trakcie własnej migracji albo dopiero ją planujesz — daj sobie czas na audyt stanu zero i na mapowanie URL. To dwie rzeczy, na których oszczędzanie mści się najboleśniej. Wszystko inne da się uratować w locie. Te dwie — niekoniecznie. I jeszcze jedno: nie rób migracji pod presją arbitralnej daty („musimy wejść do końca kwartału”), bo każdy tydzień ściskanej harmonogramowej stawki to dziesiątki tysięcy złotych problemów po premierze. Lepiej wejść dwa tygodnie później w pełnej formie niż na czas z dziurami, które będą kosztować przez kolejne pół roku.

Trzy metryki, które obserwuj dłużej niż 12 tygodni

Wynik po 12 tygodniach, który opisaliśmy w tym artykule, to wartość ustabilizowana w skali kwartału — ale nie wszystkie efekty migracji pojawiają się w tak krótkim horyzoncie. Trzy metryki, na które warto patrzeć przez cały rok po premierze, to: udział ruchu z long taila (frazy z mniej niż 100 wyszukiwaniami miesięcznie), liczba domen odsyłających z nowymi linkami oraz cytowania w AI Overviews i odpowiedziach modeli językowych. Long tail rośnie wolno, bo to tysiące małych fraz, z których każda indywidualnie nie ma szans na szybkie przebicie się — ale w sumie po 6–12 miesiącach potrafi dodać 30–50% ruchu do bazy. Domeny odsyłające reagują na lepszą jakość treści i szybszy serwis, ale linki nie pojawiają się z dnia na dzień — redakcje innych serwisów linkują do tego, co wydaje się wartościowe i stabilne, a stabilność mierzy się miesiącami. Cytowania w AI Overviews są najwolniejszym sygnałem — modele językowe często aktualizują swoje „pamięci” cytowań co kilka tygodni, a jakość sygnału rośnie stopniowo wraz z poprawą struktury danych.

Jeśli masz szansę monitorować te trzy metryki przez pełny rok po migracji, dostaniesz znacznie pełniejszy obraz tego, czy inwestycja w migrację się zwróciła. W naszym case’ie, po 12 miesiącach od premiery (czyli po 9 miesiącach od momentu, w którym publikowaliśmy raport 12-tygodniowy), ruch organiczny łącznie wzrósł o 78% względem bazowego poziomu sprzed migracji, a liczba domen odsyłających — o 42%. I to są liczby, które uzasadniają projekt ekonomicznie — nawet jeśli w pierwszych 6 tygodniach CFO wciąż patrzy podejrzliwie na linię wykresu, która spadła zanim zaczęła rosnąć.