조건부 HTTP 요청과 304 캐시 검증

ETag, Last-Modified, If-Modified-Since/If-None-Match와 304 Not Modified 응답을 사용하는 조건부 요청으로 Googlebot이 변경되지 않은 페이지를 다시 다운로드하지 않고 대규모 사이트의 크롤 예산을 보존하는 방법을 설명합니다.

최초 게시: 2026년 6월 28일 · 최근 업데이트: 2026년 8월 9일 · Advanced
언어
이 페이지의 근거 신호 1개

조건부 요청은 Googlebot이 페이지를 다시 다운로드하기 전에 “마지막 크롤링 후 바뀌었나요?”라고 묻는 방식입니다. If-Modified-Since를 Last-Modified와, If-None-Match를 ETag와 비교하고, 바뀐 것이 없으면 서버가 본문 없는 304 Not Modified를 반환해 크롤러가 기존 사본을 재사용합니다. 전체 페이지 대신 대략 1킬로바이트만 전송합니다. 둘 다 있으면 Google은 ETag를 선호하며, 모든 크롤링에 헤더를 보내지는 않고, 304가 색인 신호를 고정하지도 않습니다. 드물게 바뀌는 URL이 많은 대규모 사이트의 크롤 효율성 수단이지 순위 요소는 아닙니다. 항상 전체 본문과 200을 반환하거나, 요청마다 바뀌는 ETag를 만들거나, 실제 변경을 반영하지 않는 Last-Modified를 쓰면 효과가 사라집니다.

TL;DR — 조건부 요청을 사용하면 Googlebot이 페이지를 다시 다운로드하는 대신 캐시된 사본을 검증할 수 있습니다. If-Modified-Since(Last-Modified 헤더와 비교) 및/또는 If-None-Match(ETag와 비교)를 보내고, 바뀐 것이 없으면 서버는 본문 없는 304 Not Modified를 반환해 크롤러가 사본을 재사용합니다. 전체 페이지가 100 KB+라면 대략 ~1 KB입니다. 둘 다 있으면 ETag가 우선합니다. Google은 날짜 형식 문제가 없는 ETag를 권고하지만 둘 다 설정하라고 말합니다. Google이 모든 크롤링에 헤더를 보내는 것은 아니며 용도에 따라 AdsBot이 보낼 가능성이 더 큽니다. 조건부 헤더 없이도 선제적으로 304를 제공할 수 있고, 304가 색인 신호를 고정하지도 않습니다. 이를 무력화하는 세 가지 잘못된 설정은 항상 200 반환, 불안정한 ETag(타임스탬프, 요청별 토큰, CDN 노드별 차이), 실제 변경을 추적하지 않는 Last-Modified입니다. 대규모 사이트의 크롤 효율성 수단이지 순위 요소가 아니며 크롤 속도, 빈도, 예산과도 다릅니다.

Evidence for this claim Google may send If-Modified-Since or If-None-Match, but a site must not assume every crawler request will contain either conditional header. Scope: official protocol/provider documentation and production verification Confidence: high · Verified: Troubleshoot Google Search crawling errors Evidence for this claim Conditional requests use validators such as ETag and Last-Modified with If-None-Match or If-Modified-Since. Scope: Current official or standards documentation. Confidence: high · Verified: RFC 9110: Conditional requests Evidence for this claim A 304 response indicates a conditional request can reuse a stored representation and does not include a message body. Scope: Current official or standards documentation. Confidence: high · Verified: RFC 9110: 304 Not Modified

정확한 메커니즘

크롤 속도는 Googlebot이 얼마나 빠르게 가져오는지, 크롤 빈도는 얼마나 자주 다시 오는지에 관한 것입니다. 조건부 요청은 개별 재크롤링에 얼마나 적은 비용으로 응답할 수 있는지에 관한 것으로, 크롤러와 서버가 두 쌍의 HTTP 헤더를 사용해 수행하는 검증 핸드셰이크입니다.

서버가 보냄(응답 헤더)크롤러가 다시 보냄(요청 헤더)검증 방법
Last-Modified: <date>If-Modified-Since: <date>날짜 비교
ETag: "<fingerprint>"If-None-Match: "<fingerprint>"콘텐츠 ID 비교

단계별 흐름은 다음과 같습니다.

  1. 첫 크롤링에서 서버는 Last-Modified 날짜 및/또는 ETag 지문과 함께 200 OK 페이지를 반환합니다.
  2. 이후 크롤링에서 Googlebot은 마지막으로 본 날짜를 되돌려 보내는 If-Modified-Since 및/또는 ETag를 되돌려 보내는 If-None-Match를 보낼 수 있습니다.
  3. 서버가 이를 확인합니다. 관련 내용이 바뀌지 않았다면 상태와 헤더만 있고 응답 본문은 없는 304 Not Modified를 반환합니다.
  4. Googlebot은 지난번 크롤링한 버전을 재사용합니다. 콘텐츠가 바뀌었다면 서버는 전체 본문과 함께 200 OK를 반환합니다.

Google은 핸드셰이크를 거의 그대로 설명합니다. “Google’s crawlers that support caching will send the ETag value returned for a previous crawl of that URL in the If-None-Match header. If the ETag value sent by the crawler matches the current value the server generated, your server should return an HTTP 304 (Not modified) status code with no HTTP body.” (번역) “캐싱을 지원하는 Google 크롤러는 해당 URL의 이전 크롤링에서 반환된 ETag 값을 If-None-Match 헤더로 보냅니다. 크롤러가 보낸 ETag가 서버가 생성한 현재 값과 일치하면 서버는 HTTP 본문 없이 HTTP 304(Not modified) 상태 코드를 반환해야 합니다.”

Evidence for this claim Google documents heuristic HTTP caching and support for ETag and Last-Modified validators for crawlers that support caching. Scope: official protocol/provider documentation and production verification Confidence: high · Verified: Things to Know about Google web crawling
The validator makes the recrawl conditional: unchanged content returns a lightweight 304, while a real change returns the full 200 response. 출처: Google Search Central

A crawler revalidates its saved copy by sending If-None-Match with an ETag or If-Modified-Since with a date. The server compares that validator. If the representation is unchanged, it returns 304 Not Modified without a response body and the crawler reuses its saved copy. If the representation changed, the server returns 200 OK with the full updated response body.

© Patrick Stox LLC · CC BY 4.0 ·

ETag와 Last-Modified, 그리고 Google이 ETag를 선호하는 이유

두 검증자 모두 지원됩니다. Google 크롤링 문서의 설명입니다. “Google’s crawling infrastructure supports heuristic HTTP caching as defined by the HTTP caching standard, specifically through the ETag response- and If-None-Match request header, and the Last-Modified response- and If-Modified-Since request header.” (번역) “Google의 크롤링 인프라는 HTTP 캐싱 표준이 정의한 휴리스틱 HTTP 캐싱을 지원하며, 구체적으로 ETag 응답/If-None-Match 요청 헤더와 Last-Modified 응답/If-Modified-Since 요청 헤더를 사용합니다.”

Evidence for this claim Google documents heuristic HTTP caching and support for ETag and Last-Modified validators for crawlers that support caching. Scope: official protocol/provider documentation and production verification Confidence: high · Verified: Things to Know about Google web crawling

둘 다 있으면 ETag가 우선합니다. “If both ETag and Last-Modified response header fields are present in the HTTP response, Google’s crawlers use the ETag value as required by the HTTP standard.” (번역) “HTTP 응답에 ETag와 Last-Modified 응답 헤더 필드가 모두 있으면 Google 크롤러는 HTTP 표준에 따라 ETag 값을 사용합니다.” Google만의 특성이 아니라 HTTP 명세이며, Ahrefs의 304 Not Modified 용어집에서 설명한 우선순위 규칙과 같습니다. If-None-MatchIf-Modified-Since를 함께 사용하면 If-None-Match가 우선합니다.

ETag를 선호하는 이유는 콘텐츠 지문인 불투명 문자열이라 Last-Modified에서 흔한 날짜 파싱 함정을 피하기 때문입니다. Google의 권고는 다음과 같습니다. “For Google’s crawlers specifically, we recommend using ETag instead of the Last-Modified header to indicate caching preference as ETag doesn’t have date formatting issues.” (번역) “특히 Google 크롤러에는 ETag가 날짜 형식 문제를 일으키지 않으므로 캐싱 선호도를 나타낼 때 Last-Modified 대신 ETag 사용을 권고합니다.” Last-Modified를 사용한다면 날짜는 HTTP 표준(Weekday, DD Mon YYYY HH:MM:SS Timezone) 형식이어야 하며, 그렇지 않으면 Google이 파싱하지 못할 수 있습니다. 실무적으로는 가능하면 둘 다 설정하라는 것이 Google의 조언입니다.

추가 신호로 Cache-Control: max-age도 있습니다. 필수는 아니지만 콘텐츠가 바뀌지 않을 것으로 예상하는 초 수를 설정해 크롤러가 재크롤링 시점을 판단하도록 도울 수 있습니다. 비대칭성에 주의하세요. Google의 크롤링 인프라는 max-age를 힌트로 따르지만 다른 Cache-Control 지시문을 브라우저처럼 처리하지는 않습니다.

304가 하는 일과 하지 않는 일

전송량 측면의 효과는 큽니다. 304에는 본문이 없으므로 Gary Illyes의 대략적인 비교에 따르면 전체 페이지의 100 KB+ 대신 ~1 KB 수준입니다. 생성 비용도 낮고(전체 렌더링이나 데이터베이스 쿼리가 불필요), Google 처리 비용도 낮습니다(본문을 다시 파싱·렌더링하거나 전체 색인 파이프라인을 다시 실행하지 않음).

그러나 304가 하지 않는 일을 정확히 알아야 합니다. 순위 신호를 고정하지 않습니다. Google의 상태 코드 지침은 304에서 본문을 다시 가져오지 않았어도 색인 파이프라인이 “may recalculate signals for the URL,” (번역) *“URL의 신호를 다시 계산할 수 있다”*고 설명합니다. 304콘텐츠 다운로드와 재처리를 건너뛰지 모든 후속 평가를 막지는 않습니다. “304를 제공해 순위를 고정”하는 방법은 없습니다.

Google이 항상 묻지 않는 것은 정상입니다

대부분의 글이 놓치는 세부사항은 Googlebot이 모든 요청에 조건부 헤더를 보내지는 않는다는 점입니다. Google의 크롤링 오류 문서는 다음과 같이 설명합니다: “Google generally supports the If-Modified-Since and If-None-Match HTTP request headers for crawling. Google’s crawlers don’t send the headers with all crawl attempts; it depends on the use case of the request (for example, AdsBot is more likely to set the If-Modified-Since and If-None-Match HTTP request headers).” (번역) “Google은 일반적으로 크롤링에 If-Modified-Since와 If-None-Match HTTP 요청 헤더를 지원합니다. Google 크롤러가 모든 크롤링 시도에 이 헤더를 보내는 것은 아니며 요청의 사용 사례에 따라 달라집니다. 예를 들어 AdsBot은 두 헤더를 설정할 가능성이 더 큽니다.”

따라서 로그에서 Googlebot이 If-None-Match를 거의 보내지 않더라도 설정이 망가졌다는 뜻은 아닙니다. 해당 크롤링에서 Google이 묻지 않았을 수 있습니다. 개별 크롤러와 페처도 제공하는 제품에 따라 캐싱을 사용할 수도, 사용하지 않을 수도 있다고 Google은 설명합니다.

반대로, 잘 활용되지 않는 구현 세부사항이 있습니다. 조건부 헤더를 받지 않아도 304를 제공할 수 있습니다. Google의 설명입니다: “Independently of the request headers, you can send a 304 (Not Modified) HTTP status code and no response body for any Googlebot request if the content hasn’t changed since Googlebot last visited the URL. This will save your server processing time and resources, which may indirectly improve crawl efficiency.” (번역) “요청 헤더와 관계없이 Googlebot이 마지막으로 URL을 방문한 뒤 콘텐츠가 바뀌지 않았다면 모든 Googlebot 요청에 본문 없는 304를 보낼 수 있습니다. 서버 처리 시간과 리소스를 절약해 간접적으로 크롤 효율성을 개선할 수 있습니다.” 고급 CDN/엣지 기법이며 잘못 적용하면 위험합니다. 실제로 바뀐 콘텐츠에 304를 제공하는 것은 검증자가 거짓말하는 실패입니다. 신선도를 꾸미는 지름길이 아니라 엣지 최적화로 취급하세요.

크롤 예산에 중요한 이유

절감 효과가 가장 크게 누적되는 대상은 Google의 크롤 예산 지침이 지목하는 드물게 바뀌는 URL 비중이 큰 대규모 사이트입니다. 롱테일 SKU를 가진 전자상거래 카탈로그, 뉴스 및 출판사 아카이브, 대형 문서 사이트가 해당합니다. 이런 사이트에서는 이전 크롤링과 바이트 단위로 같은 페이지를 다시 다운로드하는 데 크롤 예산의 상당 부분을 쓸 수 있습니다. 이를 304로 응답하면 새 페이지와 변경 페이지에 예산을 돌릴 수 있습니다.

솔직히 다소 김 빠지는 점은 Google이 모두 이미 사용한다고 보고하는 것이 아니라 더 많이 도입해 달라고 요청한다는 것입니다. Illyes는 Googlebot 가져오기 중 캐시 가능한 비율이 웹 성장에도 지난 십 년간 약 0,026%에서 0,017%로 감소했다고 말했습니다. 활용도가 낮은 수단이며 “Crawling December” 글의 섹션 제목도 거의 문자 그대로 “Allow us to cache, pretty please.” (번역) *“제발 캐시할 수 있게 해 주세요.”*입니다. 대부분의 사이트는 이를 설정하지 않았습니다.

조건부 요청을 무력화하는 흔한 잘못된 설정

검증자를 설정했다고 이점을 얻는 것은 아닙니다. 사이트가 조용히 망가뜨리는 방법은 세 가지, 정확히는 네 가지입니다.

1. 항상 전체 본문과 200을 반환함

가장 흔한 실패는 아무것도 하지 않는 것입니다. 서버가 검증자를 설정하지 않거나 확인하지 않아 변경 여부와 관계없이 모든 크롤링이 전체를 다시 다운로드합니다. 캐싱 계층을 전혀 구성하지 않은 CMS/서버 스택에서 흔한 기본 상태이며 Illyes가 벗어나라고 권하는 상태입니다.

2. 모든 요청에서 바뀌는 ETag

겉보기에는 올바른 탓에 더 까다롭습니다. ETag를 삽입된 타임스탬프, 요청별 또는 세션별 토큰, 요청 ID, 빌드 시간을 넣은 산출물처럼 불안정한 값에서 계산하면 화면 콘텐츠가 같아도 모든 응답이 “새” ETag를 받습니다. If-None-Match가 일치하지 않아 서버는 304를 반환할 근거가 없습니다. 해결책은 요청마다 달라지는 값이 아니라 실제 응답 본문의 해시 또는 안정적인 콘텐츠 버전 식별자에서 ETag를 만드는 것입니다.

3. CDN/클러스터 노드별 차이

가까운 문제로, 서로 다른 원본 노드가 동일한 콘텐츠에 서로 다른 약한 ETag를 생성할 수 있습니다. CDN이나 크롤러가 노드를 번갈아 사용하면 안정적인 값을 보지 못해 깨끗한 304를 얻지 못한 채 계속 재검증합니다. 인스턴스별 상태가 아니라 콘텐츠에서 결정론적으로 ETag를 만들거나 전체 플릿의 ETag 생성을 중앙화하세요.

4. 실제 변경을 반영하지 않는 Last-Modified

Last-Modified가 렌더링할 때마다 “현재”로 찍히거나 푸터의 자동 업데이트 저작권 연도 같은 사소한 변경으로 올라가면 날짜가 늘 새로워 불필요한 전체 재크롤링을 일으킵니다. 반대로 값이 오래됐거나 조작되면 Google의 신뢰를 약화합니다. Google이 사이트맵 lastmod에 적용하는 정직성 원칙과 같습니다. 중요한 변경을 검증 가능하게 반영할 때만 사용하세요. 크롤 빈도 글에서 다루는 lastmod 논리가 Last-Modified HTTP 헤더에도 동일하게 적용됩니다.

Illyes의 경계 사례: 304가 깨진 페이지를 고정할 때

직관에 반하고 거의 다뤄지지 않아 별도로 강조할 가치가 있습니다. Illyes는 304가 “엄청나게 역효과를 낼” 수 있다고 설명했습니다. 서버 버그로 비어 있고 깨진 페이지가 200으로 제공되고, 크롤러는 일시적 오류로 보고 재확인을 예약합니다. 여전히 깨진 페이지가 이번에는 올바르게 304(“변경 없음”)를 보고하면 크롤러는 오류 상태가 지속되는 “실제” 콘텐츠라고 결론 내리고 재확인 빈도를 낮춥니다. 그의 단계별 설명은 크롤러가 “오류가 지속 가능하다는 것을 학습”하는 것으로 끝납니다. 실제로 일어나느냐는 질문에는 그렇다고, 자주냐는 질문에는 절대 아니라고 답하며 “but it’s worth keeping this somewhere deep in your mind because debugging it is an absolute nightmare.” (번역) *“디버깅이 정말 악몽이므로 마음 깊은 곳에 기억해 둘 가치가 있습니다.”*라고 말합니다. 조건부 요청은 기반 콘텐츠 생성이 망가졌을 때 오류를 고착할 수 있으므로 불안정한 원본 서버 위에 덧붙이지 마세요.

Bing의 처리 방식

Google 전용 기능이 아니며 Bing의 지원은 더 오래되고 명시적이라고도 할 수 있습니다. Bing은 Live Search 시절인 2008년에 RFC-2616 준수 조건부 GET을 발표했습니다. 마지막 크롤링 후 페이지가 바뀌지 않았다면 “일반적으로 페이지를 다운로드하지 않으며”, 마지막 다운로드 시간을 담은 If-Modified-Since와 가능한 경우 ETag를 담은 If-None-Match를 보냅니다. 현재 Bing은 이를 크롤 효율성이라는 추적 가능한 지표로 묶습니다. Fabrice Canel은 이를 “how often we crawl and discover new and fresh content per page crawled.” (번역) *“크롤링한 페이지당 새롭고 신선한 콘텐츠를 크롤링하고 발견하는 빈도”*라고 정의합니다. 변경되지 않은 콘텐츠의 불필요한 재크롤링은 이 점수를 직접 낮춥니다. 같은 검증자가 두 검색엔진에 쓰이며 Bing은 개념에 점수판을 제공할 뿐입니다.

Evidence for this claim Conditional requests use validators such as ETag and Last-Modified with If-None-Match or If-Modified-Since. Scope: Current official or standards documentation. Confidence: high · Verified: RFC 9110: Conditional requests

순위에 영향을 주나요?

아닙니다. 크롤 속도 및 크롤 예산 글과 같은 기준을 유지하세요. 조건부 요청은 순위 요소가 아니라 크롤 효율성 및 리소스 수단입니다. 어떤 공식 출처도 ETag/If-Modified-Since/304를 순위와 연결하지 않습니다. 대규모 또는 자주 업데이트되는 사이트에서 새 콘텐츠와 변경 콘텐츠를 더 빨리 크롤링하고 색인하게 하는 간접 이점은 있지만, 효율적인 크롤링 자체는 순위 신호가 아닙니다.

작동 여부를 확인하는 방법

정답은 서버 로그에 있습니다. Googlebot이 If-None-Match/If-Modified-Since 요청 헤더를 보내는지, 서버가 304로 응답하는지 확인하세요. 실제 데이터가 드물어 Dave Smart의 Tame the Bots 서버 로그 연구가 가치 있습니다. 검증된 Googlebot 트래픽을 모니터링한 결과 요청 중 약 1,3%만 304를 받았고 대부분은 200이었습니다. If-None-Match 요청은 이전 가져오기 직후 같은 URL을 다시 요청할 때 몰리는 경향이 있었습니다. 결론은 지침과 같습니다. 소규모 사이트에서는 드물지만 많이 크롤링되는 사이트에서는 “상당한 절감”이 가능합니다. 소규모 사이트에서 높은 304 비율을 기대하지 말고 규모가 클 때 중요하다고 보세요.

조건부 요청과 속도, 빈도, 예산의 차이

크롤 예산 관련 개념을 구분하면 다음과 같습니다.

  • 크롤 속도 — Googlebot이 얼마나 빠르게 가져오는지(공급 측면, 서버 상태에 따라 제한)
  • 크롤 빈도 — 알려진 URL을 얼마나 자주 다시 가져오는지(인기도 + 오래됨)
  • 크롤 예산 — 수요 + 용량 범위, 즉 Google이 크롤링할 수 있고 원하는 URL 집합
  • 조건부 요청 — 개별 재크롤링에 얼마나 적은 비용으로 응답하는지. 크롤링 속도나 빈도를 바꾸지 않고 변경되지 않은 페이지 방문을 거의 무료로 만들어 동일한 콘텐츠에 예산을 낭비하지 않게 합니다.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.