HTTP 응답 헤더에 내부 링크 그래프를 인코딩하여 65,000페이지를 99초에 크롤링한 실험
핵심
저자는 자신의 웹사이트 65,000페이지를 HTML 파싱 없이 HTTP 응답 헤더만 읽어 99초 안에 크롤링했다. 내부 링크와 제목 계층 정보를 Base64url 인코딩된 JSON으로 헤더에 직접 담은 새로운 접근 방식의 실험이다.
문제 제기와 아이디어
SEO Week 2026에서 LLM 크롤러들이 렌더링된 DOM 처리에 어려움을 겪는다는 논의 중에 저자가 제기한 핵심 질문:
"웹사이트가 모든 크롤러, 스크래퍼, LLM에 완벽히 이해되도록 하기 위해 할 수 있는 가장 작고, 빠르고, 심플한 일은 무엇인가?"
기존의 Robots.txt, 사이트맵, llms.txt, Schema.org 같은 방법들은 모두 크롤러가 HTML을 다운로드하고 파싱해야 한다고 가정한다. 그 대신 저자가 시도한 것:
- 전체 내부 링크 그래프를 JSON으로 인코딩
- Base64url 인코딩 후 HTTP 응답 헤더에 직접 삽입
- 페이지의 제목(heading) 계층도 두 번째 헤더에 포함
구현 방식
헤더 구조
Cloudflare Worker를 통해 모든 응답에 다음 헤더들 추가:
X-Internal-Links: [base64url-encoded JSON]
X-Internal-Links-Encoding: json+base64url
X-Internal-Links-Bytes: 1455
X-Internal-Links-Count: 31
X-Headings: [base64url-encoded JSON]
X-Headings-Encoding: json+base64url
X-Headings-Bytes: 534
X-Headings-Count: 8
디코딩하면:
- X-Internal-Links: 해당 페이지의 모든 내부 링크 목록
["/", "/blog", "/articles", ...] - X-Headings: 페이지의 제목 구조
[{"l":1,"t":"AI Adoption Rate..."},{"l":2,"t":"Frequently Asked Questions"}...]
왜 헤더인가?
- 8KB~32KB 용량: 구조화된 메타데이터 배송에 충분
- 헤더는 먼저 간다: WAF이 본문을 차단해도, 403/500 응답이어도, JavaScript 렌더링이 필요해도 헤더는 클라이언트에 도착
- 가볍고 빠르다: 본문 파싱이 필요 없음
성능 측정
Run 1: 콜드 캐시 (초기)
- 65,000페이지 크롤링: 14분 14초
- RPS: 76 (초당 요청)
- 병목: Worker가 매번 동작하고 엣지 캐시가 비어있음
Run 2: 워밍 캐시 (Cache-Control 추가 후)
- 65,000페이지 크롤링: 99초 (1분 39초)
- RPS: 660 (최고 969)
- 8.6배 향상: Cloudflare 엣지가 커스텀 헤더를 포함한 응답을 캐시하자 Worker 부하 급감
Run 3: 100URL 프로브 (캐시 제외, 양쪽 헤더 포함)
- 총 소요 시간: 1.88초
- 모든 URL (100/100)에서 성공 (200 응답)
- X-Internal-Links: p95 레이턴시 364ms, 최대 1,967바이트
- X-Headings: p95 레이턴시 같음, 최대 662바이트
- 합산 헤더 크기: p95 기준 2.3KB (8KB 예산 내)
- 평균 페이지당: 31개 링크, 7.9개 제목
SEO 인사이트 (헤더 데이터만 사용)
크롤링 후 65,000개 JSON 페이로드 분석 결과:
- 27,372페이지 (41.9%): 내부 백링크 없음 (고아 페이지, 사이트맵으로만 접근 가능)
- 27,659페이지: 홈페이지 탐색으로 접근 불가능
- 클릭 깊이: 페이지의 54%가 홈페이지에서 4클릭 이상 깊음, 53%는 깊이 6에 위치
- Gini 계수: 0.918 (거의 독점적 수준) — 상위 10개 페이지가 전체 내부 링크의 17% 차지
- 클러스터 불평등: 동일한 구조의 국가 폴더들(각 301페이지)이 중위 백링크 수에서 199~1의 극심한 차이
이 수준의 구조적 문제는 Screaming Frog, Sitebulb, Ahrefs 같은 도구로는 "홈페이지 감사"만으로는 절대 잡지 못했을 것.
SEO/AEO/GEO에 미치는 영향
전통 SEO 활용
- 내부 링크 그래프: 고아 페이지, 막다른 페이지, 클릭 깊이, 허브 식별, 집중도 측정
- 제목 계층: 계층 검증, 주제 클러스터링, 중복 탐지
- 정규 링크, hreflang, 콘텐츠 해시: 추가 요청 없이 함께 제공
- Last-edited 타임스탬프: 크롤러가 재방문 필요성 판단
- 페이지 등급 신호: "이것은 1차 허브" vs "3차 롱테일 페이지" 표시
AEO/GEO (답변 엔진 최적화)
Perplexity, ChatGPT, Gemini 같은 AI 엔진들은 구조화된 정보를 선호:
X-Headings: (H1-H6 리스트)
X-Page-Topic: "ecommerce conversion benchmarks Bangladesh 2026"
X-Page-Entities: ["Bangladesh", "ecommerce", "conversion rate", "2026"]
X-Page-Summary: (base64url 280자 요약)
크롤러가 "페이지를 이해하기를 원한다"고 기도하는 대신, 이해를 그대로 건넨다.
기술적 SEO 운영
- 엣지에서 크롤 우선순위 지정: 허브 페이지에
X-Crawl-Priority: high삽입 - 변경 감지: 링크 그래프 해시로 HTML 비교 없이 네비게이션 변화 감지
- 렌더링 독립성: CMS가 canonical 태그를 빠뜨려도 플랫폼이 진실 발행
선행 기술과의 차이
RFC 8288 - Link HTTP 응답 헤더 (2017)
표준이지만 페이지 전체 내부 링크 그래프에 부적절한 형식 (rel당 하나씩). 신택스가 빠르게 팽창.
Cloudflare Agent Readiness 프레임워크 (Q1 2026)
공식적으로 Link 헤더를 세 가지 에이전트 발견성 표준 중 하나로 나열하지만, 표준 rel만 대상. 전체 링크 그래프 패턴은 없음.
llms.txt (Sept 2024, Jeremy Howard / Answer.AI)
사이트 설명 마크다운 파일. 의도는 유사하지만:
- 별도 파일 (추가 왕복)
- 정적 큐레이션 (페이지별 아님)
- 저자 방식: 추가 요청 없음, 페이지별 정확도, 기계-정확한 페이로드
JSON-LD via Accept 콘텐츠 협상
별도 요청 필요, 클라이언트 옵트인 필요. 저자 방식: 무조건 모든 응답에 도착.
Open Graph / 구조화된 데이터를 헤더로 (제안 스레드들)
이론에 머무름. 저자의 각도: Google 파싱을 기대하지 않음. 자체 도구, SEO/AEO 파이프라인, 모니터링, 개발 팀, 앞서가는 에이전트를 위해 발행.
프로덕션 장애 사례
배포 1시간 전, X-Headings 헤더 추가 후:
curl https://data.stateglobe.com/
HTTP/2 500
원인: 홈페이지의 230개 링크 + 길은 제목 리스트가:
- X-Internal-Links: ~10.8KB
- X-Headings: ~6.9KB
- 합계: ~17KB (원점의 응답 헤더 크기 제한 초과)
대부분의 서브페이지 (31개 링크, 540바이트)는 잘 작동. 허브 페이지(가장 중요한 페이지)가 깨짐.
방어적 헤더 예산 모듈 (해결책)
TypeScript 모듈 src/headers.ts 추가:
import { attachStructuralHeaders } from "./headers";
return attachStructuralHeaders(
new Response(html, { status: 200 }),
{
url: req.url,
links: getInternalLinks(page), // 크기 제한 적용
headings: getHeadings(page), // 크기 제한 적용
}
// 기본값: 헤더당 6KB, 합계 12KB
);
동작:
- 헤더별 상한 (기본 6KB): 각 리스트를 10% 단위로 축소하여 Base64url 인코딩 크기 맞춤
- 합계 하드 캡 (기본 12KB): 개별로는 맞지만 합계가 초과하면, 제목 리스트 먼저 자르고 필요시 링크 리스트도 자름
- 잘림 텔레메트리:
X-Internal-Links-Truncated: 1및X-Internal-Links-Original: 230추가로 모니터링 가능
스트레스 테스트: 5,000개 링크 + 5,000개 제목 → 11.4KB 출력, 안전하게 캡 내 (500 에러 없음).
배포 전 체크리스트
헤더 크기 제한은 실제
- Cloudflare 기본값: ~16KB
- 많은 원점: 8KB 이하
- 합산 헤더가 맞지 않으면 5xx 응답
허브 페이지가 위험 구역
- 200+ 링크, 50개 제목 항목 → 쉽게 초과 가능
- 모든 허브를 배포 전 테스트
방어적으로 캡 적용
- 헤더당 6KB, 합계 12KB 등 하드 제한
- 200개 중 50개 링크 배송 > 페이지 500 에러
엣지에서 캐시
- Worker는 기본 캐시 안 함:
caches.default.put+Cache-Control: public, s-maxage=7200, max-age=300필요 - 76 RPS vs 660 RPS 차이
배포 후 캐시 퍼지
- 새 헤더 형식 후 한 번 퍼지, 이전 응답 우회
HEAD 요청은 피할 것
- Cloudflare와 많은 원점이 HEAD와 GET에 다르게 응답
- 헤더 손실 가능성
누락된 헤더는 "데이터 부재"로 처리
- 초기 분석에서 256개 페이지가 "막다른 페이지"로 태그됨 → 실제론 헤더 누락 페치
- 재크롤링 전에 결론 도출 금지
자신의 도메인으로만 범위
- 다른 사람 사이트의 WAF를 뚫는 우회 도구 아님
엔터프라이즈: 혼자 배포하지 말 것
- 개발팀, 플랫폼/SRE팀, 보안팀 포함
- 이 변경은 엣지층, 원점 응답 예산, 봇/보안 규칙을 모두 건드림
- 스테이징 → 서명 → 단일 디렉토리 → 전체 확대 순서
구조, 3문장 요약
- 페이지당 작은 JSON 페이로드(링크/제목/주제) 생성 후 캐시
- 모든 응답에 Base64url 인코딩 헤더로 페이로드 첨부, 크기 캡 적용해 헤더 합계 원점 제한 내 유지
- 응답을 엣지에서 캐시하면 두 번째 크롤은 본질상 무료
머신러닝, 복잡한 인프라, 프로토콜 변경 없음. 단일 개발자가 오후 한 번에 배포 가능하고, 부주의하면 5분 안에 프로덕션 깨뜨릴 수 있는 수준.
더 큰 그림: 헤더를 발행 표면으로
전통적 사고 vs 새 관점
지난 30년: 모든 것을 본문(body)에 집어넣고 기계가 파싱하길 원함. 크롤러, 파서 강화. 매 요청마다 번역 비용 지불.
HTTP 응답의 실체:
헤더 ← 기계 읽기용, 빠름, 구조화, 거의 무료
본문 ← 인간 읽기용, 느림, 비구조화, 비쌈
변화의 신호
LLM과 답변 엔진이 웹의 주요 소비자가 되면서, 구조화된 의도를 발행하는 사이트를 보상. HTTP 헤더는 구조화된 의도를 발행하기 위한 가장 빠르고 싸고 보편적인 장소.
새 프로토콜, 표준, W3C 위원회 불필요. JSON을 헤더에 넣고 신중하게 배포하면 됨.
향후 방향
완성된 것
✅ 방어적 헤더 예산 라이브러리 (src/headers.ts)
탐색 중
- 주제 임베딩: 256차원 양자화 벡터, Base64 인코딩. LLM이 페이지를 읽지 않고 비교 가능
- 크롤 예산 프로토콜: "65,000페이지, 240허브, 마지막 전체 인덱싱 14시간 전" 헤더로 크롤러 방문 빈도 결정 지원
- 공개 호스트 헤더 크롤러 API: 자신의 사이트 URL 입력하면 99초 전체 감사 실행 (무료 SaaS)
- AEO 친화적 헤더 팩: X-Headings + X-Page-Topic + X-Cite-Snippet + X-Page-Summary (기본값, 크기 제한)
- 청크 헤더 지원: X-Internal-Links-1, X-Internal-Links-2, ... (매우 큰 허브도 전체 그래프 배송)
현재 라이브 데모 (data.stateglobe.com)
주의: 안전한 실험을 위해 의도적으로 페이로드 자름. 200+ 링크 허브는 완전한 그래프 배송 시 청크 헤더 필요. 공개 데모는:
- 깨끗한 200-OK 응답 (링크+제목의 대표 부분집합)
- 제한 없는 기법은 리포지토리 로컬 Worker, 소규모 데모 사이트에서 확인 가능
배포 전 읽기 자료
코드 저장소
- GitHub: github.com/metehan777/http-header-link-graph (Cloudflare Worker + Rust 크롤러 + Python 인사이트 파이프라인, MIT 라이센스)
리포트
- HTML 노드 그래프: https://metehan.ai/graph-input/link-graph
- JSON 리포트: https://metehan.ai/graph-input/seo-graph-report.json
- CSV 리포트: https://metehan.ai/graph-input/seo-header-report.csv
- 헤더 요약: https://metehan.ai/graph-input/seo-header-summary.json
마무리
이 실험은 크롤링 문제 해결로 시작했으나, SEO Week 2026에서 전체 SEO/AEO/GEO 스택을 보는 새로운 방식으로 발전했다:
HTTP 헤더는 가장 과소평가된 웹 발행 표면이며, 기계가 더 많이 읽을수록 더 중요해질 것.
결과:
- 65,000페이지, 99초, HTML 파싱 0회
- 전통 도구로는 찾지 못했을 41% 고아율 발견
- 100URL 프로브: 1.88초, 양쪽 헤더 완벽 디코딩
- 프로덕션 홈페이지 500 에러 (무료 교훈)
- 헤더에 담을 수 있는 것의 100개 새 아이디어
자신의 사이트가 있고, 오후 한두 시간, 개발팀 협력이 가능하다면 시도해보자. 먼저 눈에 띄는 것은 변화의 작음. 두 번째는 사이트 이해 방식이 얼마나 바뀌는지.
——
감사의 말: iPullRank 팀과 Michael King에게 SEO Week 2026 개최로 이 아이디어가 탄생할 수 있는 공간을 제공해주셔서 감사합니다.