Modelowane listy odbiorców nie zawierają konkretnych osób, tylko prawdopodobieństwa. Wyjaśniam, jak powstają, gdzie ich szukać w panelu i jak czytać ich raporty.
Rozmowa zawsze wygląda podobnie. Administrator serwera pokazuje mi logi, w nich setki żądań od Googlebota w ciągu kilku minut, i mówi, że ustawił już w pliku robots.txt opóźnienie, ale to nic nie dało. Otwieram plik i faktycznie — jest tam linijka `Crawl-delay: 10`. Leży sobie spokojnie od dwóch lat i nie robi absolutnie nic.
To jedno z tych przekonań, które w polskim internecie żyje własnym życiem. Reguła istnieje, jest opisana w dziesiątkach poradników, część robotów naprawdę ją czyta — tylko że ten robot, o który zwykle chodzi, konsekwentnie ją pomija. I mówi o tym otwarcie od kilku lat.
Poniżej rozbieram to na części: skąd Crawl-delay się wzięła, co dokładnie miała robić, dlaczego Google jej nie obsługuje i czym w praktyce reguluje się tempo odwiedzin robota, jeśli serwer naprawdę nie wyrabia.
Plik robots.txt jest starszy niż większość dzisiejszych narzędzi SEO. Powstał w 1994 roku jako umowa dobrej woli między autorami stron a autorami robotów: właściciel serwisu zapisuje w pliku tekstowym, czego nie chce udostępniać, a robot to szanuje. Nic więcej — żadnego mechanizmu wymuszania, żadnej instytucji, która by ten format zatwierdzała.
Przez pierwsze dwadzieścia pięć lat nie było nawet formalnej specyfikacji. Google złożyło projekt standardu w IETF w 2019 roku i do dziś jest to projekt, a nie opublikowany dokument standaryzujący. Wcześniej każdy większy operator robota implementował ten format po swojemu, dopisując do niego to, czego mu brakowało.
Crawl-delay jest właśnie takim dopiskiem. Nie ma jej w oryginalnej konwencji z 1994 roku i nie ma jej w projekcie złożonym przez Google. Wprowadziły ją poszczególne wyszukiwarki w czasach, gdy przeciętny serwer WWW był znacznie słabszy niż dziś, a agresywny robot potrafił go realnie położyć. Zapotrzebowanie było oczywiste, więc każdy rozwiązał je u siebie — i stąd cały późniejszy bałagan.
Warto to zapamiętać, bo tłumaczy resztę tekstu: Crawl-delay nigdy nie była częścią wspólnego standardu, tylko lokalnym rozszerzeniem kilku wyszukiwarek. Traktowanie jej jako uniwersalnej dyrektywy jest nieporozumieniem, które utrwaliły poradniki przepisywane jeden z drugiego.
Składnia jest banalna. Regułę umieszcza się w bloku dotyczącym konkretnego robota, razem z pozostałymi dyrektywami:
I tu pojawia się pierwszy problem: ta interpretacja nie jest jednolita. W jednych implementacjach liczba oznacza dosłownie odstęp w sekundach między żądaniami. W innych jest to wartość mapowana na wewnętrzne poziomy tempa — coś w rodzaju „wolno”, „bardzo wolno” — więc różnica między wartością 5 a 7 może w praktyce nie istnieć. Zdarzały się też implementacje liczące to jako liczbę żądań w jednostce czasu.
Drugi problem jest arytmetyczny i widać go dopiero, gdy się policzy. `Crawl-delay: 10` przy pełnym wykorzystaniu limitu daje maksymalnie 8640 żądań na dobę. Dla serwisu wizytówkowego to dużo więcej, niż potrzeba. Dla sklepu z kilkudziesięcioma tysiącami adresów produktowych, filtrów i paginacji to gwarancja, że robot nigdy nie zobaczy całego serwisu. Widzę to na kontach, które przejmuję: ktoś kiedyś wpisał tam wartość „na wszelki wypadek”, nikt tego nie policzył, a potem dziwimy się, że nowe produkty wchodzą do indeksu tygodniami.
Trzecia rzecz, mniej oczywista: robot czyta plik robots.txt z pamięci podręcznej. Google odświeża go najczęściej raz na dobę, więc każda zmiana w tym pliku — także dotycząca tempa — nie działa natychmiast. To nie jest narzędzie do gaszenia pożaru, który trwa w tej chwili.
Zacznijmy od faktu, bo bywa on podawany w wątpliwość: Google nie obsługuje reguły Crawl-delay i nigdy jej nie obsługiwało. Nie jest to domysł ani wniosek z obserwacji logów. Google potwierdziło to wprost w komunikacie z 2019 roku, w którym wymieniło reguły ignorowane przez swój parser — obok `crawl-delay` znalazły się tam `noindex` i `nofollow` zapisywane w robots.txt. Od września 2019 roku parser tych linijek po prostu nie bierze pod uwagę i nie zgłasza ich nawet jako błędu.
Powód jest techniczny i, moim zdaniem, sensowny. Google nie ustala tempa indeksowania jako jednej globalnej liczby. Robi to na podstawie dwóch rzeczy jednocześnie: tego, ile serwer jest w stanie znieść, i tego, ile treści w danym serwisie warto odwiedzić. Pierwsza wartość jest wyliczana dynamicznie — robot obserwuje czasy odpowiedzi i błędy, i jeśli serwer zaczyna zwalniać, sam zmniejsza liczbę równoległych połączeń. Druga zależy od tego, jak często treść się zmienia i jaka jest jej wartość dla wyszukiwarki.
Sztywna liczba sekund w pliku tekstowym jest wobec takiego mechanizmu narzędziem bardzo grubym. Nie odróżnia strony głównej od nieskończonej kombinacji filtrów, nie odróżnia godzin szczytu od nocy i nie wie nic o tym, że serwer właśnie dostał dodatkowe zasoby. Google woli mierzyć, jak serwer faktycznie reaguje, niż wierzyć deklaracji, którą ktoś wpisał dwa lata temu.
Jest jeszcze argument, o którym mówi się rzadziej: reguła bywała nadużywana. Wartości rzędu kilkuset sekund wpisywane bez zrozumienia konsekwencji skutecznie odcinały serwis od indeksowania, a potem właściciel zgłaszał problem z widocznością, nie łącząc jednego z drugim.
Skoro Google jej nie czyta, pojawia się pytanie, czy usunąć ją z pliku. Zwykle odpowiadam, że nie ma pośpiechu, bo linijka nie jest szkodliwa dla Google — jest po prostu przez niego pomijana. Ale dla innych robotów działa.
Jeśli decyduję się zostawić regułę, to w bloku skierowanym do konkretnych robotów, nie w bloku z gwiazdką. Powód jest prosty: blok z gwiazdką jest jedynym, jaki czyta wiele prostych implementacji, a mieszanie w nim reguł adresowanych do jednej wyszukiwarki prowadzi do trudnych do wyłapania pomyłek. Przy okazji warto sprawdzić plik testerem robots.txt w Search Console — narzędzie pokaże, jak Google interpretuje poszczególne bloki, i od razu widać, że linijka z opóźnieniem nie jest tam w ogóle brana pod uwagę.
Jeżeli serwer naprawdę nie wyrabia, mam do dyspozycji dwie drogi i obie omijają robots.txt.
Pierwsza to narzędzie do ograniczania częstotliwości indeksowania w Search Console. To starsza część panelu, dostępna z widoku statystyk indeksowania. Ustawia się w niej maksymalne tempo dla całego hosta, a ustawienie wygasa po dziewięćdziesięciu dniach i wraca do trybu automatycznego. Traktuję to jako rozwiązanie na trudny okres — migrację, kampanię, awarię infrastruktury — a nie jako stan docelowy. Trzeba też pamiętać, że działa ono na poziomie hosta, więc obniża tempo dla całej domeny, także dla tych adresów, które chcielibyśmy przeindeksować szybko.
Druga droga to odpowiedzi serwera, o których piszę osobno poniżej, bo to jedyny mechanizm działający natychmiast.
Czego natomiast nie robię: nie próbuję spowolnić robota przez `Disallow`. Blokada w robots.txt nie zmniejsza tempa — ona wyłącza odwiedzanie danych adresów całkowicie. Jeżeli zablokuję nią cały katalog, żeby „odciążyć serwer”, to po prostu wypadną mi z aktualizacji strony, na których mi zależy, a Google przy okazji może zostawić w indeksie ich adresy bez treści. Nie blokuję też Googlebota po adresie IP na zaporze, bo z jego perspektywy witryna staje się niedostępna, a to zupełnie inny komunikat niż „zwolnij”.
Jest jeden sposób, na który Googlebot reaguje szybko: kod odpowiedzi HTTP. Jeśli serwer zaczyna zwracać `429`, `500` lub `503`, robot zmniejsza tempo, a przy dłuższym utrzymywaniu takiego stanu przestaje odwiedzać dany adres. To dokładnie ten mechanizm, którym Google zastąpiło potrzebę czytania Crawl-delay — sygnał pochodzi z serwera, więc jest zawsze aktualny.
Z tym narzędziem trzeba jednak uważać, bo ma bardzo krótki termin przydatności. Google jasno pisze, że taki stan ma być tymczasowy — rzędu dnia czy dwóch. Utrzymywanie kodów błędu tygodniami skończy się usuwaniem adresów z indeksu, bo dla wyszukiwarki strona, która od dawna zwraca błąd serwera, po prostu przestała istnieć.
Dwie rzeczy, na które zwracam uwagę przy takim ratowaniu serwera. Po pierwsze, kod musi być z rodziny błędów serwera albo `429`, a nie `403` czy `404` — te dwa ostatnie mówią „tej strony nie ma i nie będzie”, a nie „wróć później”. Po drugie, jeśli można, warto dodać nagłówek `Retry-After`, bo daje robotowi konkretną informację, kiedy spróbować ponownie.
Równolegle zawsze otwieram raport statystyk indeksowania w Search Console. Interesuje mnie tam nie tylko łączna liczba żądań, ale przede wszystkim średni czas odpowiedzi i stan hosta, a także rozbicie żądań na typy plików i na cel — czyli odświeżanie znanych adresów kontra wykrywanie nowych. Bez tego rozbicia dyskusja o tempie robota jest zgadywaniem: bywa, że połowa ruchu robota to pobieranie obrazków i plików skryptów, a nie stron.
Za większością zgłoszeń typu „Googlebot zabija mi serwer” nie stoi zbyt szybki robot, tylko zbyt wiele adresów wartych odwiedzenia z jego punktu widzenia. Filtry generujące kombinacje, sortowania, kalendarze rezerwacji, wyniki wyszukiwania wewnętrznego, identyfikatory sesji w adresie — każdy z tych mechanizmów potrafi zamienić serwis o dwóch tysiącach stron w serwis o dwóch milionach adresów. Robot nie robi wtedy nic złego. Po prostu dostał listę do odwiedzenia i ją realizuje.
Dlatego kolejność moich działań jest odwrotna niż odruch większości osób. Najpierw sprawdzam, ile adresów serwis w ogóle produkuje i ile z nich ma sens. Potem porządkuję to, co po naszej stronie: linkowanie wewnętrzne, adresy kanoniczne, blokady dla wzorców generujących nieskończone kombinacje. Ograniczanie tempa zostawiam na koniec, jako doraźny środek na czas, gdy porządkowanie jeszcze trwa.
Dodam, że możliwości sterowania tym z panelu jest teraz mniej niż jeszcze wiosną — narzędzie do obsługi parametrów URL w Search Console zostało w kwietniu wycofane, więc decyzje o tym, co robot ma odwiedzać, podejmuje się wyłącznie po stronie serwisu. Tym bardziej nie ma sensu liczyć na to, że jedna linijka w pliku tekstowym załatwi sprawę.
Podsumowując: Crawl-delay to reguła z innej epoki, obsługiwana przez część robotów i konsekwentnie pomijana przez Googlebota, który tempo ustala sam na podstawie zachowania serwera. Jeśli chcesz na to tempo wpłynąć, masz do dyspozycji narzędzie w Search Console na dłuższy okres, kody odpowiedzi serwera na sytuację awaryjną i — najskuteczniej — porządek w tym, ile adresów Twój serwis w ogóle wystawia światu.
Używamy plików cookies, aby ułatwić Ci nawigację oraz wykonywanie określonych funkcji. Szczegółowe informacje o wszystkich plikach cookies znajdziesz w każdej kategorii zgody poniżej.
Pliki cookies oznaczone jako "Niezbędne" są przechowywane w Twojej przeglądarce, ponieważ są one kluczowe dla zapewnienia podstawowych funkcji strony.
Używamy również plików cookies firm trzecich, które pomagają nam analizować, w jaki sposób korzystasz z tej strony, zapamiętują Twoje preferencje oraz dostarczają treści i reklamy odpowiednie dla Ciebie. Te pliki cookies będą przechowywane w Twojej przeglądarce tylko za Twoją uprzednią zgodą.
Możesz zdecydować, czy chcesz włączyć lub wyłączyć niektóre bądź wszystkie te pliki cookies, jednak wyłączenie niektórych z nich może wpłynąć na Twoje doświadczenia podczas przeglądania strony.
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| __cf_bm | 13 minutes | Cloudflare bot management — distinguishes humans from bots. |
| rc::* | Persistent | Google reCAPTCHA — localStorage holding anti-bot challenge state. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| wpEmojiSettingsSupports | Session | WordPress — sessionStorage flag caching whether the browser can render emoji (feature detection). |
| ytidb* | Persistent | YouTube — IndexedDB storing playback/search state for embedded videos. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| _ga_* | 400 days | Google Analytics 4 — persists session state per property. |
| _ga | 400 days | Google Analytics — distinguishes unique users via a client id. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| NID | 183 days | Google — stores preferences for personalized ads. |
| fr | 90 days | Meta — encrypted Facebook id and browser id for ads. |
| _gcl_au | 90 days | Google AdSense/Ads — experiments with advertising efficiency (conversion linker). |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| __Secure-YNID | 180 days | |
| YSC | Session | |
| __Secure-ROLLOUT_TOKEN | 180 days | |
| VISITOR_INFO1_LIVE | 180 days | |
| VISITOR_PRIVACY_METADATA | 180 days | |
| datr | 400 days | |
| sb | 400 days | |
| wd | 7 days |