조건부 HTTP 요청과 304 캐시 검증
ETag, Last-Modified, If-Modified-Since/If-None-Match와 304 Not Modified 응답을 사용하는 조건부 요청으로 Googlebot이 변경되지 않은 페이지를 다시 다운로드하지 않고 대규모 사이트의 크롤 예산을 보존하는 방법을 설명합니다.
언어
이 페이지의 근거 신호 1개
- 관련 라이브 도구HTTP Header Checker
조건부 요청은 Googlebot이 페이지를 다시 다운로드하기 전에 “마지막 크롤링 후 바뀌었나요?”라고 묻는 방식입니다. If-Modified-Since를 Last-Modified와, If-None-Match를 ETag와 비교하고, 바뀐 것이 없으면 서버가 본문 없는 304 Not Modified를 반환해 크롤러가 기존 사본을 재사용합니다. 전체 페이지 대신 대략 1킬로바이트만 전송합니다. 둘 다 있으면 Google은 ETag를 선호하며, 모든 크롤링에 헤더를 보내지는 않고, 304가 색인 신호를 고정하지도 않습니다. 드물게 바뀌는 URL이 많은 대규모 사이트의 크롤 효율성 수단이지 순위 요소는 아닙니다. 항상 전체 본문과 200을 반환하거나, 요청마다 바뀌는 ETag를 만들거나, 실제 변경을 반영하지 않는 Last-Modified를 쓰면 효과가 사라집니다.
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 ModifiedTL;DR — 조건부 요청은 Googlebot이 페이지를 다시 다운로드하기 전에 서버에 *“마지막으로 가져간 뒤 이 페이지가 바뀌었나요?”*라고 묻는 것입니다. 바뀌지 않았다면 서버는 페이지 본문 없이 작은
304 Not Modified응답을 보내고 크롤러는 이미 가진 사본을 재사용합니다. 양쪽의 작업을 줄이지만 의미 있는 효과는 대규모 사이트에서 주로 나타나며 순위를 높이지는 않습니다.
조건부 요청이란 무엇인가요?
보통 Googlebot이 페이지를 원하면 전체를 다운로드합니다. 조건부 요청은 더 영리합니다. 크롤러가 “지난 방문 때와 실제로 다를 때만 페이지를 보내 주세요”라고 요청합니다.
이때 이전 크롤링에서 기억한 약간의 추가 정보를 사용합니다.
- 날짜 — “지난번 이 페이지를 받았을 때 특정 날짜에 마지막으로 수정됐다고 했습니다. 더 새로운 것이 있나요?”
- 지문 — “지난번 이 페이지에 ID(
ETag)를 주었습니다. 그 ID가 여전히 같나요?”
아무것도 바뀌지 않았다면 서버는 **304 Not Modified**를 반환합니다. 이 응답에는 페이지가 붙어 있지 않고 “이전과 같음”을 뜻하는 짧은 메시지만 있습니다. Googlebot은 모든 것을 다시 다운로드하지 않고 지난번 저장한 사본을 재사용합니다.
무언가 바뀌었다면 서버는 평소처럼 전체 페이지(200 OK)를 보내고 크롤러는 새 사본을 가져갑니다.
중요한 이유
거의 바뀌지 않는 제품 페이지가 백만 개 있는 대형 온라인 스토어를 생각해 보세요. 조건부 요청이 없으면 Googlebot은 다시 올 때마다 지난주와 동일한 페이지를 전부 다시 다운로드해 막대한 대역폭과 서버 작업을 낭비합니다. 조건부 요청을 사용하면 대부분의 방문에 작은 “변경 없음” 응답만 보내고, 크롤러는 실제로 바뀌었거나 새로 생긴 페이지에 시간을 쓸 수 있습니다.
이점은 전부 효율성입니다. 검색엔진이 사이트에서 수행하려는 크롤링 양을 뜻하는 크롤 예산의 일부입니다.
솔직한 주의사항
기대하기 전에 알아둘 두 가지가 있습니다.
- 주로 대규모 사이트에 중요합니다. 소규모 사이트에서는 절감량이 작아 설정할 가치가 없는 경우가 많습니다. 제가 이전에 썼듯이 소규모 웹사이트에서
304가 제공하는 캐싱 기회는 “그다지 중요하지 않습니다.” - 순위를 높이지 않습니다. 효율적으로 크롤링한다고 검색 결과에서 올라가지는 않습니다. 대규모 사이트의 새 페이지와 변경 페이지를 조금 더 빨리 크롤링하는 데 도움이 될 뿐입니다.
정확한 헤더, Google이 실제로 지원한다고 밝힌 내용, 사이트가 조용히 망가뜨리는 세 가지 방식, 크롤 속도 및 크롤 빈도와의 차이를 보고 싶다면 고급 탭으로 전환하세요.
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 ModifiedTL;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입니다. 대규모 사이트의 크롤 효율성 수단이지 순위 요소가 아니며 크롤 속도, 빈도, 예산과도 다릅니다.
정확한 메커니즘
크롤 속도는 Googlebot이 얼마나 빠르게 가져오는지, 크롤 빈도는 얼마나 자주 다시 오는지에 관한 것입니다. 조건부 요청은 개별 재크롤링에 얼마나 적은 비용으로 응답할 수 있는지에 관한 것으로, 크롤러와 서버가 두 쌍의 HTTP 헤더를 사용해 수행하는 검증 핸드셰이크입니다.
| 서버가 보냄(응답 헤더) | 크롤러가 다시 보냄(요청 헤더) | 검증 방법 |
|---|---|---|
Last-Modified: <date> | If-Modified-Since: <date> | 날짜 비교 |
ETag: "<fingerprint>" | If-None-Match: "<fingerprint>" | 콘텐츠 ID 비교 |
단계별 흐름은 다음과 같습니다.
- 첫 크롤링에서 서버는
Last-Modified날짜 및/또는ETag지문과 함께200 OK페이지를 반환합니다. - 이후 크롤링에서 Googlebot은 마지막으로 본 날짜를 되돌려 보내는
If-Modified-Since및/또는ETag를 되돌려 보내는If-None-Match를 보낼 수 있습니다. - 서버가 이를 확인합니다. 관련 내용이 바뀌지 않았다면 상태와 헤더만 있고 응답 본문은 없는
304 Not Modified를 반환합니다. - 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 crawlingA 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-Match와 If-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은 개념에 점수판을 제공할 뿐입니다.
순위에 영향을 주나요?
아닙니다. 크롤 속도 및 크롤 예산 글과 같은 기준을 유지하세요. 조건부 요청은 순위 요소가 아니라 크롤 효율성 및 리소스 수단입니다. 어떤 공식 출처도 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 집합
- 조건부 요청 — 개별 재크롤링에 얼마나 적은 비용으로 응답하는지. 크롤링 속도나 빈도를 바꾸지 않고 변경되지 않은 페이지 방문을 거의 무료로 만들어 동일한 콘텐츠에 예산을 낭비하지 않게 합니다.
AI 요약
고급 버전을 압축하면 다음과 같습니다.
- 조건부 요청 = “바뀌었나요?” Googlebot은
If-Modified-Since(Last-Modified와 비교) 및/또는If-None-Match(ETag와 비교)를 보냅니다. 바뀌지 않으면 서버가 **본문 없는304 Not Modified**를 반환하고 크롤러는 사본을 재사용합니다. - 둘 다 있으면 ETag가 우선합니다. Google은 날짜 형식 문제가 없는
ETag를 권고하지만 둘 다 설정하라고 말합니다.Cache-Control: max-age는 선택적인 보조 재크롤링 시점 힌트입니다. - **
304는 ~1 KB, 전체 페이지는 100 KB+**이며 재다운로드와 재처리를 건너뜁니다. 그러나 Google이 신호를 다시 계산할 수 있으므로 색인 신호를 고정하지는 않습니다. - Google은 항상 헤더를 보내지 않으며 용도에 따라 AdsBot이 보낼 가능성이 더 큽니다. 조건부 헤더 없이도 선제적으로
304를 제공할 수 있습니다. - 이를 무력화하는 세 가지 설정은 항상 전체 본문과
200반환, 불안정한ETag, **실제 변경을 추적하지 않는Last-Modified**이며 사이트맵lastmod에도 같은 정직성 원칙이 적용됩니다. - 경계 사례: 깨졌거나 빈 페이지 위에
304를 제공하면 Googlebot이 오류를 영구적인 것으로 취급할 수 있습니다(Illyes). - Bing은 2008년부터 RFC 준수 조건부 GET을 지원했고 이를 “크롤 효율성”으로 추적합니다.
- 도입률은 낮고 감소 중이며(지난 십 년간 약 0,026% → 0,017%), 대규모 사이트에서 활용도가 낮은 수단이고 순위 요소가 아닙니다.
- 서버 로그에서 검증하세요(
304비율,If-None-Match존재 여부). 실제 데이터는 소규모 사이트에서는 드물고 규모가 클 때 의미가 있음을 보여 줍니다.
공식 문서
조건부 요청과 크롤러 캐싱에 관한 1차 출처 문서입니다.
- Google 웹 크롤링에 관해 알아둘 사항 —
ETag/If-None-Match,Last-Modified/If-Modified-Since, ETag 우선순위,Cache-Control: max-age힌트를 다룹니다. 이전/search/docs/...경로에서 이동했으며 지침은 같습니다. - Crawling December: HTTP 캐싱 — 문서 업데이트의 배경인 Gary Illyes의 2024년 12월 글입니다.
- Google 검색 크롤링 오류 문제 해결 —
If-Modified-Since/304메커니즘, AdsBot 예시, 조건부 헤더 없이 304를 제공할 수 있다는 내용을 다룹니다. - HTTP 상태 코드, 네트워크 및 DNS 오류 — Google이
304를 처리하는 방식과 신호가 다시 계산될 수 있으며 색인에 부정적 영향은 없다는 설명입니다. - 크롤 예산 최적화 — 상위 개념과 실제로 신경 써야 할 사이트를 설명합니다.
- 사이트맵 구축 및 제출 —
Last-Modified헤더 규율과 닮은lastmod정직성 원칙입니다.
Bing / Microsoft
- Live Search 크롤러 개선 발표 — Bing의 2008년 RFC-2616 조건부 GET 발표(
If-Modified-Since+If-None-Match/ETag)입니다. - bingbot 시리즈: 크롤 효율성 극대화 — Bing의 “크롤 효율성” 지표와 변경되지 않은 콘텐츠 재크롤링이 이를 낮추는 이유입니다.
- Bing Webmaster Tools — Crawl Control — 크롤 속도 수단으로, 개별 크롤 효율성 수단인 조건부 요청과 대비됩니다.
출처의 인용문
Google과 Bing의 공개 발언입니다. 각 링크는 출처 페이지의 인용 구절로 이동하는 딥 링크입니다.
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 요청 헤더를 사용합니다.” — Google. 인용문으로 이동
- “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 값을 사용합니다.” 인용문으로 이동
- “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 사용을 권고합니다.” 인용문으로 이동
- “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 크롤러는 이전 크롤링에서 반환된 ETag 값을 If-None-Match 헤더로 보냅니다. 현재 값과 일치하면 서버는 HTTP 본문 없이 HTTP 304 상태를 반환해야 합니다.” 인용문으로 이동
Google — 헤더를 보내는 시점과 선제적 304 허용
- “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은 일반적으로 두 요청 헤더를 지원하지만 모든 크롤링 시도에 보내지는 않으며 사용 사례에 따라 달라집니다. 예를 들어 AdsBot이 보낼 가능성이 더 큽니다.” 인용문으로 이동
- “If our crawlers send the If-Modified-Since header, the header’s value is the date and time the content was last crawled. Based on that value, the server may choose to return a 304 (Not Modified) HTTP status code with no response body, in which case Google will reuse the content version it crawled the last time.” (번역) “크롤러가 If-Modified-Since를 보내면 값은 마지막 크롤링 날짜와 시간입니다. 서버가 본문 없는 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 요청에 본문 없는 304를 보낼 수 있습니다. 서버 처리 시간과 리소스를 절약해 간접적으로 크롤 효율성을 개선할 수 있습니다.” 인용문으로 이동
Google의 Gary Illyes (LinkedIn — 304 역효과 실패 방식)
- “HTTP 304 (not modified) is super useful to signal crawlers that the content they’re accessing hasn’t changed since it was last crawled, but it can also backfire spectacularly.” (번역) “HTTP 304는 콘텐츠가 마지막 크롤링 후 바뀌지 않았음을 알리는 데 매우 유용하지만 엄청나게 역효과를 낼 수도 있습니다.” 게시물 읽기
- “Does this ever happen? Yes. Often? Absolutely not. But it’s worth keeping this somewhere deep in your mind because debugging it is an absolute nightmare.” (번역) “이런 일이 생기나요? 예. 자주인가요? 절대 아닙니다. 하지만 디버깅이 악몽이므로 마음 깊은 곳에 기억할 가치가 있습니다.” 게시물 읽기
Bing(Live Search), Fabrice Canel (2008년 조건부 GET 발표)
- “Live Search supports conditional get as defined by RFC 2616 (Section 14.25), and generally will not download the page unless it has changed since the last time it crawled it.” (번역) “Live Search는 RFC 2616(14.25절)이 정의한 조건부 GET을 지원하며 일반적으로 마지막 크롤링 후 페이지가 바뀐 경우에만 다운로드합니다.” 인용문으로 이동
about-crawling 캐싱 인용문이 있는 두 Google 문서 페이지는 JavaScript로 렌더링되어 직접 자동 수집에 실패했습니다. 인용문은 여러 독립 매체를 통해 문구 그대로 확인했지만 최종 확정 전에 실제 페이지와 다시 대조해야 합니다. Illyes의 LinkedIn, Bing 2008, 크롤링 오류 문제 해결 인용문은 실제 출처에서 확인했습니다. 조건부 요청을 구현할 가치가 있나요?
모든 사이트에 필요한 것은 아닙니다. 서버 구성을 건드리기 전에 시간을 들일 가치가 있는지 판단하세요.
Is implementing conditional requests worth it for my site?
SOP: 조건부 요청을 올바르게 구현하는 방법
대규모 사이트에서 조건부 요청 지원을 추가하거나 고치는 반복 가능한 절차입니다. 측정, 구현, 검증 순서로 진행하세요.
1. 실제로 문제가 있는지 확인합니다.
서버 로그에서 검증된 Googlebot 트래픽을 가져오세요. 변경되지 않은 URL 요청 대부분이 전체 본문과 200을 반환하고 If-None-Match/If-Modified-Since 헤더가 거의 없다면 개선 여지가 있습니다. 변경되지 않은 페이지에서 이미 304가 보인다면 얻을 것이 거의 없을 수 있습니다.
2. 안정적이고 콘텐츠 기반인 ETag를 생성합니다.
실제 응답 본문의 해시 또는 안정적인 콘텐츠 버전 식별자에서 ETag를 계산하세요. 타임스탬프, 요청별 또는 세션별 토큰, 요청 ID, 서버 노드마다 달라지는 값에서 만들지 마세요. 변경되지 않은 같은 URL을 두 번 요청해 ETag 값이 같고 CDN/원본 플릿 전반에서도 같은지 확인하세요.
3. 정직한 Last-Modified를 설정합니다.
현재 렌더링 시각이나 푸터 연도만 바뀐 시각이 아니라 마지막 중요한 콘텐츠 변경 날짜/시간으로 Last-Modified를 설정하세요. HTTP 표준(Weekday, DD Mon YYYY HH:MM:SS Timezone)에 맞게 형식화하세요. 가능하면 ETag와 Last-Modified를 둘 다 설정하며 Google은 ETag를 우선합니다.
4. 304를 올바르게 반환합니다.
If-None-Match가 현재 ETag와 일치하거나 If-Modified-Since가 Last-Modified보다 오래되지 않았고 아무것도 바뀌지 않았다면 응답 본문 없이 상태와 헤더만 있는 304 Not Modified를 반환하세요. 원본 앞의 프록시 또는 CDN이 이를 제거하지 않는지 확인하세요.
5. 선택 사항: Cache-Control max-age 힌트를 추가합니다.
콘텐츠가 바뀌지 않을 것으로 예상하는 초 수를 Cache-Control: max-age=<seconds>에 보조 재크롤링 시점 신호로 설정하세요. 힌트이지 보장은 아닙니다.
6. 로그에서 검증한 뒤 그대로 둡니다.
몇 주 뒤 로그를 다시 확인하세요. 변경되지 않은 페이지에서는 Googlebot의 If-None-Match 요청에 304로 응답하고 실제로 콘텐츠가 바뀌었을 때만 200을 반환해야 합니다. 소규모 사이트에서는 높은 304 비율을 기대하지 마세요.
가드레일: 실제로 바뀐 페이지에 304를 제공하지 말고 불안정한 원본 서버에 조건부 요청을 덧붙이지 마세요. 깨졌거나 빈 페이지 위에 제공한 304 때문에 Googlebot이 오류를 영구적인 것으로 취급할 수 있습니다.
피해야 할 오해와 실수
노력 낭비나 조용한 장애를 일으키는 반복적인 오해입니다.
-
“Googlebot은 항상 If-Modified-Since/If-None-Match를 보내므로 로그에 없으면 서버가 망가진 것이다.” 거짓입니다. Google은 모든 크롤링에 헤더를 보내지 않으며 용도에 따라 달라진다고 명시합니다. 기본 Search 크롤러는 일관되지 않게 보내고 AdsBot은 보낼 가능성이 더 큽니다. Tame the Bots의 로그 데이터에서는 테스트 사이트 요청의 2%보다 훨씬 적은 비율만
304를 받았습니다. -
“304는 Google이 내 순위/신호를 다시 평가하지 않는다는 뜻이다.” 거짓입니다. Google 문서는
304에서도 색인 파이프라인이 URL의 신호를 다시 계산할 수 있다고 설명합니다. 콘텐츠 본문의 다운로드와 재처리만 건너뜁니다. -
“ETag를 설정하면 자동으로 304를 받는다.”
ETag가 불안정하면 거짓입니다. 타임스탬프, 요청별 토큰, 노드별 상태에서 만든ETag는 요청마다 바뀌어If-None-Match와 일치하지 않습니다. 얼핏 올바르게 구성된 것처럼 보여 진단은 더 어렵습니다. -
“Last-Modified는 존재하기만 하면 되고 아무 날짜나 괜찮다.” 거짓입니다. 매 렌더링의 “현재” 시각이나 푸터 변경으로 올라가 실제 콘텐츠 변경을 추적하지 못하면 재크롤링을 낭비하거나 신호에 대한 Google의 신뢰를 낮춥니다. 사이트맵
lastmod와 같은 원칙입니다. -
“304는 조건부 GET에 대한 반응형 응답으로만 쓸 수 있다.” 거짓입니다. 서버가 콘텐츠가 바뀌지 않았음을 독립적으로 안다면 Google은 모든 Googlebot 요청에 본문 없는
304를 선제적으로 반환하도록 명시적으로 허용합니다. -
“조건부 요청을 구현하면 순위가 오른다.” 공식 출처로 입증되지 않았습니다. 문서화된 이점은 크롤 및 서버 효율성이며, 대규모 사이트에서 새 콘텐츠를 더 빨리 크롤링하는 데 도움이 될 수 있지만 순위 요소는 아닙니다.
-
“거대 엔터프라이즈 사이트에만 중요하다.” 긴급성 측면에서는 대체로 맞습니다. Google은 드물게 바뀌는 콘텐츠가 많은 대규모 사이트를 대상으로 합니다. 그러나 메커니즘과 잘못된 설정은 모든 사이트에 적용됩니다. 소규모 사이트에서는 설정할 가치가 거의 없을 뿐입니다.
curl로 URL의 캐싱 검증자 확인하기
서버가 보내는 검증자와 이를 되돌려 보냈을 때 304를 반환하는지 확인하세요.
1) 응답 헤더 확인(ETag와 Last-Modified 찾기)
curl -sI https://example.com/some-page | grep -iE 'etag|last-modified|cache-control'
# ETag: "a1b2c3d4e5"
# Last-Modified: Thu, 22 Jan 2026 01:28:49 GMT
# Cache-Control: max-age=940432) ETag로 조건부 요청하기 — 304가 반환돼야 함
curl -sI https://example.com/some-page \
-H 'If-None-Match: "a1b2c3d4e5"'
# HTTP/2 304 ← correct: server confirms nothing changed, sends no body
# HTTP/2 200 ← if you get this on an unchanged page, your validators aren't working3) 대신 날짜로 조건부 요청하기
curl -sI https://example.com/some-page \
-H 'If-Modified-Since: Thu, 22 Jan 2026 01:28:49 GMT'
# HTTP/2 304불안정한 ETag 감지하기
변경되지 않은 같은 URL이 연속 요청에서 서로 다른 ETag를 반환하면 ETag가 불안정합니다(타임스탬프/토큰 기반). 그러면 If-None-Match가 일치하지 않습니다.
# Request twice; the two ETag values should be IDENTICAL for an unchanged page
for i in 1 2; do curl -sI https://example.com/some-page | grep -i '^etag:'; done
# ETag: "a1b2c3d4e5"
# ETag: "a1b2c3d4e5" ← good (stable)
# ETag: "9f8e7d6c5b" ← BAD if different: your ETag changes every request접근 로그에서 304 표본 확인하기
Googlebot의 실제 조건부 요청 활동을 확인하세요. 로그 형식에 맞게 필드 위치를 조정해야 합니다. 아래는 combined-log 형식의 상태 필드를 가정합니다.
# Count status codes returned to Googlebot
grep -i 'googlebot' access.log | awk '{print $9}' | sort | uniq -c | sort -rn
# 4211 200
# 53 304 ← these are the conditional-request wins
# 12 301
# See which URLs are getting 304s
grep -i 'googlebot' access.log | awk '$9==304 {print $7}' | sort | uniq -c | sort -rn | head(사용자 에이전트 문자열을 믿기 전에 역방향 및 정방향 DNS 검사로 실제 Googlebot인지 확인하세요. 가짜 Googlebot 트래픽이 흔합니다.)
브라우저 DevTools Console 빠른 확인
Chrome DevTools Console에 붙여넣어 브라우저가 현재 페이지에서 받은 검증자를 확인하세요.
// Reads the ETag / Last-Modified the server sent for THIS page
fetch(location.href, { method: 'HEAD' }).then(r => {
console.log('ETag:', r.headers.get('etag'));
console.log('Last-Modified:', r.headers.get('last-modified'));
console.log('Cache-Control:', r.headers.get('cache-control'));
}); 검증자 → 요청 → 응답 프레임워크
- 검증자: 최초
200응답이ETag,Last-Modified또는 둘 다를 제공합니다. - 요청: 이후 가져오기가 해당 값을
If-None-Match또는If-Modified-Since로 되돌려 보냅니다. - 응답: 콘텐츠가 바뀌지 않았으면 본문 없는
304, 바뀌었으면 새 본문과 검증자를 담은200을 반환합니다. - 안정성 검사: 표현 콘텐츠가 바뀔 때 검증자가 바뀌어야 하며, 요청이 다른 서버에 도달했거나 타임스탬프를 포함했다는 이유로 바뀌면 안 됩니다.
조건부 요청 헤더 치트 시트
| 헤더 또는 상태 | 방향 | 의미 |
|---|---|---|
ETag | 응답 | 현재 표현의 식별자 |
If-None-Match | 요청 | ETag가 다를 때만 본문 반환 |
Last-Modified | 응답 | 표현에 대한 서버의 수정 시각 |
If-Modified-Since | 요청 | 이 시각 이후 바뀐 경우에만 본문 반환 |
304 Not Modified | 응답 | 캐시 사본 재사용, 응답 본문 없음 |
200 OK | 응답 | 현재 표현과 검증자 다운로드 |
검증자 확인 도구
- HTTP 헤더 검사기는
ETag,Last-Modified, 캐시 헤더, 리디렉션 간 헤더 변경을 보여 줍니다. - 브라우저 DevTools의 Network 패널에서는 최초 검증자와 반복 요청의 조건부 헤더를 검사할 수 있습니다.
curl은 가장 명확하고 재현 가능한 테스트입니다. 검증자를 캡처해 되돌려 보내고 변경되지 않은 응답이304인지 확인하세요.- 접근 로그 분석은 크롤러의 조건부 요청이 대규모로 실제
304응답을 받는지 보여 줍니다.
조건부 요청 상태 지표
조건부 적중률
지표: 304를 반환한 적격 조건부 요청. 알려 주는 것: 검증자가 변경되지 않은 본문 전송을 피하는지 여부. 추출 방법: If-None-Match 또는 If-Modified-Since가 있는 접근 로그 요청을 응답 상태별로 그룹화합니다. 벤치마크/현실적 범위: 템플릿과 변경 주기별 기준선을 설정하세요. 자주 업데이트되는 페이지는 안정적인 아카이브와 자연스럽게 다릅니다. 주기: 월간 및 캐시/CDN 변경 후.
304 응답으로 피한 바이트
지표: 전송하지 않은 것으로 추정되는 응답 본문 바이트. 알려 주는 것: 응답 수가 아닌 대역폭 이점. 추출 방법: 각 304 URL을 로그 또는 크롤링 내보내기의 최신 200 본문 크기와 비교합니다. 벤치마크/현실적 범위: 사이트의 이전 기간과 비교하세요. 보편적 목표는 정직하지 않습니다. 주기: 월간.
검증자 불안정성
지표: 확인 사이에 ETag 또는 Last-Modified가 바뀐 변경되지 않은 URL. 알려 주는 것: 요청별 또는 노드별 차이가 재검증을 무력화하는지 여부. 추출 방법: 고정 표본에 동일한 헤더 요청을 반복합니다. 벤치마크/현실적 범위: 표현이 바뀌지 않는 동안 검증자는 안정적이어야 합니다. 주기: 배포, CDN 변경 또는 로드 밸런서 변경 후.
시간을 들일 만한 자료
내 관련 글
- 304 Not Modified란?(Ahrefs SEO Glossary) — 전체 조건부 요청 흐름,
If-None-Match우선 규칙, 소규모 사이트에서304기회가 “그다지 중요하지 않지만” 대규모 사이트에서는 “좋은 기회”인 이유를 설명합니다. - 크롤 예산을 언제 걱정해야 하나요? — 크롤 예산의 의미, 수요와 용량, 누가 신경 써야 하는지를 설명합니다.
- Googlebot이란 무엇이며 어떻게 작동하나요? — Googlebot이 무엇을 얼마나 빠르게 크롤링할지 결정하는 방식입니다.
- 기술 SEO 초보자 가이드 — 크롤 효율성이 더 큰 그림에서 어디에 속하는지 설명합니다.
내 강연
- 검색 작동 방식(SlideShare) — 크롤링, 렌더링, 색인, 순위와 다시 가져올 대상을 결정하는 크롤 수요 요인을 설명합니다. 제 고정 면책 문구도 적용됩니다. “This is my understanding of systems… not going to be 100% complete or accurate.” (번역) “이는 시스템에 대한 제 이해이며 100% 완전하거나 정확하지 않을 수 있습니다.”
업계 자료
- Crawling December: HTTP 캐싱(Google Search Central) — 캐싱 활성화를 요청한 Gary Illyes의 글이자 도입률 감소 수치의 출처입니다.
- Googlebot은 Etag 헤더를 사용하나요?(Tame the Bots의 Dave Smart) — Googlebot 조건부 요청 동작을 실제 서버 로그로 연구한 드문 자료입니다.
- Google이 크롤러의 캐시 제어 헤더 처리 방식을 명확히 함(Barry Schwartz, Search Engine Land) —
ETag/Last-Modified핵심 인용문을 그대로 재현한 문서 업데이트 기사입니다. - Google의 업데이트된 크롤러 지침이 ETag를 권고(Roger Montti, Search Engine Journal) —
ETag선호 이유와 개별 크롤러의 캐싱 차이를 설명합니다. - Live Search 크롤러 개선 발표(Fabrice Canel, Bing Webmaster Blog) — Bing의 2008년 RFC-2616 조건부 GET 발표입니다.
- bingbot 시리즈: 크롤 효율성 극대화(Bing Webmaster Blog) — Bing의 “크롤 효율성” 프레임입니다.
- MDN: HTTP 조건부 요청(Mozilla) — 검증자와
304메커니즘에 대한 중립적인 명세 수준 자료입니다.
스스로 테스트하기: 조건부 요청
ETag, If-Modified-Since, 304 Not Modified에 관한 다섯 문제입니다. 각 답을 고른 뒤 확인하세요.
변경 내역
2026년 8월 9일에 업데이트됨.
편집 요약 및 기록된 변경 세부 정보입니다.변경 세부 정보
-
변경 세부 정보는 현재 영어로 제공됩니다.
전체 비교를 사용할 수 없음 — 이 수정에 대한 이전 스냅샷이 보관되지 않았습니다.
2026년 7월 18일에 업데이트됨.
편집 요약 및 기록된 변경 세부 정보입니다.변경 세부 정보
-
변경 세부 정보는 현재 영어로 제공됩니다.
전체 비교를 사용할 수 없음 — 이 수정에 대한 이전 스냅샷이 보관되지 않았습니다.