{"id":2172,"date":"2026-08-08T09:08:00","date_gmt":"2026-08-08T08:08:00","guid":{"rendered":"https:\/\/jalvo.eu\/cache-reverse-proxy-a-seo-bez-nieaktualnych-stron\/"},"modified":"2026-09-25T00:16:55","modified_gmt":"2026-09-24T23:16:55","slug":"cache-reverse-proxy-a-seo-bez-nieaktualnych-stron","status":"publish","type":"post","link":"https:\/\/jalvo.eu\/pl\/cache-reverse-proxy-a-seo-bez-nieaktualnych-stron\/","title":{"rendered":"Cache w reverse proxy a SEO: roboty bez nieaktualnych stron"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Roboty widz\u0105 nieaktualne strony, gdy proxy wci\u0105\u017c wydaje zapisane kopie i nigdy nie sprawdza ich z serwerem \u017ar\u00f3d\u0142owym. Poprawne <strong>SEO przy cache w reverse proxy<\/strong> to kr\u00f3tki TTL dla HTML, nietkni\u0119te nag\u0142\u00f3wki ETag i Last-Modified oraz prawid\u0142owa obs\u0142uga odpowiedzi 304. Google wci\u0105\u017c pokazuje stare tytu\u0142y? Nieaktualne canonicale albo przekierowania, kt\u00f3re usun\u0105\u0142e\u015b kilka tygodni temu? A mo\u017ce roboty jeszcze d\u0142ugo dostawa\u0142y z cache b\u0142\u0105d 404 lub 5xx, cho\u0107 serwer \u017ar\u00f3d\u0142owy dawno dzia\u0142a\u0142? Wtedy winne jest prawie zawsze kt\u00f3re\u015b z poni\u017cszych ustawie\u0144. Zanim zaczniesz je poprawia\u0107, sprawd\u017a te\u017c, czy ruch w og\u00f3le trafia do proxy, czyli czy <a href=\"https:\/\/jalvo.eu\/pl\/jak-skierowac-domene-na-reverse-proxy-rekordy-dns\/\">rekordy DNS kieruj\u0105 domen\u0119<\/a> na w\u0142a\u015bciwy serwer. Z cache warto te\u017c wy\u0142\u0105czy\u0107 \u015bcie\u017ck\u0119 \/.well-known\/acme-challenge\/, bo przez ni\u0105 przechodzi <a href=\"https:\/\/jalvo.eu\/pl\/lets-encrypt-za-reverse-proxy-wydawanie-certyfikatow\/\">wydawanie certyfikat\u00f3w Let&#8217;s Encrypt<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jak to si\u0119 dzieje, \u017ce reverse proxy podaje Googlebotowi nieaktualne tre\u015bci?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Proxy zwraca zapisan\u0105 odpowied\u017a, dop\u00f3ki nie minie jej w\u0142asny TTL, bez wzgl\u0119du na to, co w tym czasie zmieni\u0142o si\u0119 na serwerze \u017ar\u00f3d\u0142owym. Zwykle przyczyn\u0105 jest ustawienie, kt\u00f3re przy wdra\u017caniu wygl\u0105da\u0142o niewinnie:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>d\u0142ugi <code>proxy_cache_valid<\/code> obejmuj\u0105cy ka\u017cdy kod statusu, a nie tylko 200<\/li>\n<li><code>proxy_ignore_headers Cache-Control Expires<\/code>, kt\u00f3re wyrzuca do kosza zasady \u015bwie\u017co\u015bci ustalone przez serwer \u017ar\u00f3d\u0142owy<\/li>\n<li><code>proxy_cache_use_stale<\/code> w\u0142\u0105czone dla wszystkich b\u0142\u0119d\u00f3w, bez limitu czasu<\/li>\n<li>klucz cache bez hosta lub schematu, przez co jedna witryna (albo protok\u00f3\u0142) dostaje stron\u0119 innej<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Najgorzej jest z b\u0142\u0119dami. Dwuminutowa awaria mo\u017ce zamieni\u0107 si\u0119 w zapisany w cache b\u0142\u0105d 5xx, na kt\u00f3ry boty trafiaj\u0105 godzinami. Chcesz to potwierdzi\u0107? Por\u00f3wnaj to, co zwraca serwer \u017ar\u00f3d\u0142owy, z tym, co faktycznie dosta\u0142y boty, i zacznij od <a href=\"https:\/\/jalvo.eu\/reading-server-logs-crawl-problems\/\">problem\u00f3w z crawlowaniem w logach<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jakie nag\u0142\u00f3wki Cache-Control powinny wysy\u0142a\u0107 strony HTML?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">HTML potrzebuje kr\u00f3tkiego max-age, dopasowanego do tego, jak cz\u0119sto strona naprawd\u0119 si\u0119 zmienia. Zasoby statyczne mog\u0105 d\u0142ugo le\u017ce\u0107 w cache. CSS, JavaScript i obrazki z wersj\u0105 w nazwie pliku bezpiecznie znosz\u0105 d\u0142ugi czas \u017cycia, bo nowe wydanie i tak oznacza nowy URL. Ze stronami jest inaczej. Ten sam URL, inna tre\u015b\u0107.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Google radzi u\u017cywa\u0107 max-age, \u017ceby powiedzie\u0107 robotom, kiedy wr\u00f3ci\u0107, i ustawi\u0107 go na liczb\u0119 sekund, przez kt\u00f3re tre\u015b\u0107 ma si\u0119 nie zmienia\u0107. W <a href=\"https:\/\/developers.google.com\/search\/blog\/2024\/12\/crawling-december-caching\" rel=\"nofollow noopener\" target=\"_blank\">wpisie o tym, jak roboty Google korzystaj\u0105 z cache<\/a> jako przyk\u0142ad podano <code>Cache-Control: max-age=94043<\/code>. Najwi\u0119cej robi\u0105 tu trzy dyrektywy. <em>s-maxage<\/em> dotyczy tylko wsp\u00f3\u0142dzielonych cache, takich jak Twoje proxy. <em>max-age<\/em> obejmuje przegl\u0105darki i roboty. A <em>no-cache<\/em>? Wbrew nazwie pozwala zapisa\u0107 kopi\u0119 - trzeba j\u0105 tylko zweryfikowa\u0107 przed ka\u017cdym u\u017cyciem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ETag i Last-Modified, czyli 304 zamiast starej kopii dla robot\u00f3w<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Walidatory pozwalaj\u0105 robotowi zapyta\u0107 \u201eczy co\u015b si\u0119 zmieni\u0142o?\u201d, a je\u015bli nie, serwer odpowiada 304 Not Modified bez tre\u015bci. Wed\u0142ug <a href=\"https:\/\/developers.google.com\/search\/blog\/2024\/12\/crawling-december-caching\" rel=\"nofollow noopener\" target=\"_blank\">wskaz\u00f3wek Google Search Central o cache<\/a> Googlebot wysy\u0142a zapisany ETag w nag\u0142\u00f3wku If-None-Match, a pasuj\u0105ca warto\u015b\u0107 powinna dosta\u0107 304 bez tre\u015bci HTTP. Je\u015bli jeden URL serwuje kilka wersji, na przyk\u0142ad mobiln\u0105 i desktopow\u0105, ka\u017cda potrzebuje w\u0142asnego ETagu. Last-Modified z If-Modified-Since dzia\u0142a tak samo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W\u0142a\u015bnie tu proxy najcz\u0119\u015bciej co\u015b psuj\u0105. Kompresja gzip w locie albo przepisywanie HTML potrafi\u0105 usun\u0105\u0107 ETag, os\u0142abi\u0107 go albo zostawi\u0107 jeden tag dla dw\u00f3ch r\u00f3\u017cnych reprezentacji. Niedobrze. <a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc9111.html\" rel=\"nofollow noopener\" target=\"_blank\">Standard cache w HTTP<\/a> pozwala cache po\u0142\u0105czy\u0107 tagi klienta z w\u0142asnymi przy rewalidacji. Je\u015bli wi\u0119c serwer \u017ar\u00f3d\u0142owy odpowie 304 z tagiem, kt\u00f3rego klient nigdy nie wys\u0142a\u0142, cache musi zbudowa\u0107 pe\u0142n\u0105 odpowied\u017a 200 z zapisanej kopii. To poprawna rewalidacja (i w\u0142a\u015bnie ona powstrzymuje proxy przed wys\u0142aniem \u015blepego 304 dla tre\u015bci, kt\u00f3rej klient nigdy nie mia\u0142).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bezpieczna konfiguracja proxy_cache w nginx dla stron indeksowanych przez roboty<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Trzymaj HTML w cache kr\u00f3tko, rewaliduj zamiast pobiera\u0107 od nowa i nigdy nie przechowuj d\u0142ugo odpowiedzi z b\u0142\u0119dami. Podstawowe dyrektywy:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>proxy_cache_key $scheme$host$request_uri;<\/code> rozdziela protoko\u0142y i nazwy host\u00f3w.<\/li>\n<li><code>proxy_cache_valid<\/code> ustawiony osobno dla ka\u017cdego statusu: kr\u00f3tko dla 200, bardzo kr\u00f3tko albo wcale dla 404 i 5xx.<\/li>\n<li><code>proxy_cache_revalidate on;<\/code> od\u015bwie\u017ca wygas\u0142e wpisy \u017c\u0105daniami warunkowymi.<\/li>\n<li><code>proxy_cache_use_stale updating error timeout;<\/code> obejmuje tylko te przypadki, z czasem \u017cycia wybranym \u015bwiadomie.<\/li>\n<li><code>proxy_cache_background_update on;<\/code> od\u015bwie\u017ca wpisy tak, \u017ce odwiedzaj\u0105cy nie musi czeka\u0107.<\/li>\n<li><code>proxy_cache_lock on;<\/code> wysy\u0142a do serwera \u017ar\u00f3d\u0142owego tylko jedno \u017c\u0105danie dla brakuj\u0105cego klucza.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Nie w\u0142\u0105czaj <code>proxy_ignore_headers<\/code> dla HTML, chyba \u017ce serwer \u017ar\u00f3d\u0142owy wysy\u0142a kompletnie bezsensowne nag\u0142\u00f3wki. Dodaj <code>add_header X-Cache-Status $upstream_cache_status;<\/code> i zapisuj t\u0119 warto\u015b\u0107 w logach, \u017ceby przy ka\u017cdym \u017c\u0105daniu bota by\u0142o wida\u0107 HIT, MISS albo STALE. W praktyce to jedno pole w logu oszcz\u0119dza sporo zgadywania. Wszystko to ustawiasz zreszt\u0105 na w\u0142asnym serwerze \u017ar\u00f3d\u0142owym albo w NGINX. <a href=\"https:\/\/jalvo.eu\/services\/\">Zarz\u0105dzane proxy NGINX<\/a> mo\u017ce kierowa\u0107 ruch Twoich domen i IP, ale regu\u0142y cache ustalasz sam.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Czyszczenie i uniewa\u017cnianie cache po zmianie tre\u015bci<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Klikni\u0119cie \u201eOpublikuj\u201d powinno od razu czy\u015bci\u0107 zmienione URL-e, a nie czeka\u0107, a\u017c minie TTL. Masz kilka mo\u017cliwo\u015bci: <code>proxy_cache_purge<\/code> przez modu\u0142 zewn\u0119trzny albo NGINX Plus, segment wersji w kluczu cache, usuni\u0119cie pliku cache dla danego klucza oraz kr\u00f3tki TTL jako zabezpieczenie. Czy\u015b\u0107 powi\u0105zane strony razem - artyku\u0142, jego listingi i strony kategorii, map\u0119 witryny i feed. Zmiana statusu te\u017c wymaga natychmiastowego czyszczenia. Strona zamieni\u0142a si\u0119 w 404 albo 410? Dosta\u0142a nowe 301? Roboty b\u0119d\u0105 widzie\u0107 stary status, dop\u00f3ki ten wpis nie zniknie z cache.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nie r\u00f3\u017cnicuj cache pod boty: roboty i u\u017cytkownicy maj\u0105 widzie\u0107 to samo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Osobna wersja z cache dla Googlebota, wybierana po user agencie albo IP, ociera si\u0119 o cloaking, wi\u0119c roboty powinny korzysta\u0107 z tego samego cache co odwiedzaj\u0105cy. R\u00f3\u017cnicuj tylko po tym, co naprawd\u0119 zmienia reprezentacj\u0119, czyli Accept-Encoding i ewentualnie j\u0119zyk. Nigdy po User-Agent. Zalogowane sesje i ciasteczka personalizacji dostaj\u0105 w\u0142asne regu\u0142y omijania cache, \u017ceby prywatne strony nigdy nie trafi\u0142y do wsp\u00f3\u0142dzielonego cache. Wi\u0119cej o ryzyku w naszym poradniku o <a href=\"https:\/\/jalvo.eu\/ip-cloaking-and-seo-what-you-need-to-know-to-stay-compliant\/\">unikaniu cloakingu w SEO<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jak sprawdzi\u0107, czy roboty dostaj\u0105 \u015bwie\u017ce strony<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Testuj z zewn\u0105trz \u017c\u0105daniami warunkowymi, a od \u015brodka przez logi:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Uruchom <code>curl -I<\/code> dwa razy i por\u00f3wnaj X-Cache-Status w obu odpowiedziach.<\/li>\n<li>Wy\u015blij If-None-Match albo If-Modified-Since i oczekuj 304 z pust\u0105 tre\u015bci\u0105.<\/li>\n<li>Zmie\u0144 stron\u0119 i sprawd\u017a, czy wraca teraz jako 200 z nowym ETagiem.<\/li>\n<li>Odfiltruj w logach dost\u0119pu Googlebota i pogrupuj \u017c\u0105dania wed\u0142ug statusu cache i kodu odpowiedzi.<\/li>\n<li>U\u017cyj Sprawdzania adresu URL w Search Console, \u017ceby zobaczy\u0107 pobranie na \u017cywo.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Dobre SEO przy cache w reverse proxy sprowadza si\u0119 do czterech nawyk\u00f3w: kr\u00f3tki TTL dla HTML, nienaruszone walidatory, b\u0142\u0119dy poza cache i czyszczenie przy ka\u017cdej publikacji. I tyle. Powi\u0105zane poradniki znajdziesz w <a href=\"https:\/\/jalvo.eu\/category\/seo\/\">naszej kategorii technicznego SEO<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list \">\n<div id=\"faq-question-1790291424193-0\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Czy wy\u0142\u0105czy\u0107 cache w proxy dla Googlebota?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>u003cpu003eNie. Prowad\u017a jeden cache dla wszystkich klient\u00f3w i zamiast tego popraw TTL oraz walidatory. Regu\u0142y tylko dla bot\u00f3w gro\u017c\u0105 cloakingiem i ukrywaj\u0105 problemy, na kt\u00f3re wci\u0105\u017c trafiaj\u0105 Twoi odwiedzaj\u0105cy.u003c\/pu003e<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1790291424193-1\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Czy to problem, je\u015bli proxy zwraca robotom 304?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>u003cpu003eNie, o ile ETag albo Last-Modified naprawd\u0119 odpowiada aktualnej wersji, a odpowied\u017a 304 nie ma tre\u015bci. Takie zachowanie opisuje u003ca href=u0022https:\/\/developers.google.com\/search\/blog\/2024\/12\/crawling-december-cachingu0022 rel=u0022nofollowu0022u003edokumentacja Google o cache robot\u00f3wu003c\/au003e. Odpowied\u017a 304 staje si\u0119 problemem dopiero wtedy, gdy proxy wysy\u0142a j\u0105 dla tre\u015bci, kt\u00f3ra faktycznie si\u0119 zmieni\u0142a.u003c\/pu003e<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1790291424193-2\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Jak d\u0142ugo proxy powinno trzyma\u0107 w cache odpowiedzi 404 i 5xx?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>u003cpu003eKr\u00f3tko albo wcale, \u017ceby chwilowy b\u0142\u0105d nie zamarz\u0142 w cache. Ustaw u003ccodeu003eproxy_cache_validu003c\/codeu003e osobno dla ka\u017cdego statusu i daj kodom b\u0142\u0119d\u00f3w znacznie mniej czasu ni\u017c poprawnym stronom. A gdy celowo usuwasz stron\u0119, od razu wyczy\u015b\u0107 j\u0105 z cache.u003c\/pu003e<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Roboty widz\u0105 nieaktualne strony, gdy proxy wci\u0105\u017c wydaje zapisane kopie i nigdy nie sprawdza ich z serwerem \u017ar\u00f3d\u0142owym. Poprawne SEO [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":2150,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[182],"tags":[],"class_list":["post-2172","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-seo-pl"],"acf":[],"_links":{"self":[{"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/posts\/2172","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/comments?post=2172"}],"version-history":[{"count":1,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/posts\/2172\/revisions"}],"predecessor-version":[{"id":2182,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/posts\/2172\/revisions\/2182"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/media\/2150"}],"wp:attachment":[{"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/media?parent=2172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/categories?post=2172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/tags?post=2172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}