못 덮었던 통계를 덮었습니다 — 남은 가설은 맞았고, 대신 두 가지를 잃었습니다
앞선 글은 미해결로 끝냈습니다. 티스토리 스킨에 넣은
비콘이 POST 404 로 떨어졌습니다. 스킨은 블로그 화면을 만드는 HTML 틀이고, 비콘은
방문 기록을 통계 서버로 보내는 작은 스크립트입니다. 의심하던 셋 중 둘은 잘라냈는데 셋째 —
사이트가 자동 설치 모드라 수동 수집 경로가 애초에 안 열려 있다 — 는
확인하지 못한 채로 닫았습니다.

그 가설이 맞았습니다. 관리 화면에서 설치 모드를 스니펫 설치, 그러니까 스크립트를 제가 직접 붙여 넣는 쪽으로 바꾸자 세 호스트가 전부 204 로 돌아섰습니다. 반대쪽인 자동 설치는 클라우드플레어가 페이지를 내보낼 때 그 스크립트를 알아서 끼워 넣어 주는 방식입니다.
| 호스트 | 비콘 자리 | 전환 전 | 전환 후 |
|---|---|---|---|
birchholt.com (Hugo) | 모든 페이지에 공통으로 들어가는 head | 자동 삽입으로 집계 중 | 204 |
misiq.birchholt.com | 스킨 </body> 직전 | 404 | 204 |
checkin.birchholt.com | 스킨 </body> 직전 | 404 | 204 |
204 는 curl 이 아니라 실제 페이지를 브라우저로 열고 네트워크 탭에서 본 값입니다.
네트워크 탭은 브라우저 개발자 도구에서 오간 요청을 보여주는 화면입니다.
왜 그 단서를 붙여야 하는지가 이 글에서 제가 가장 크게 틀린 지점입니다.
이 표와 아래 curl 결과는 2026-09-02에 세 호스트의 페이지를 각각 열고
POST /cdn-cgi/rum 의 상태 코드를 읽은 값입니다.
모드가 주소를 바꿉니다

공식 FAQ 가 두 모드의 수집 주소를 아예 다르게 적어둡니다.
Using a domain proxied through Cloudflare with automatic setup will report stats back to your own domain’s
/cdn-cgi/rumendpoint. If you have installed JS snippet yourself (a manual setup), it will report back tocloudflareinsights.com/cdn-cgi/rumendpoint. — Cloudflare Web Analytics FAQ
자동은 자기 도메인으로 쏘고 프록시가 그 자리에서 받습니다. 프록시는 방문자의 요청이 Cloudflare 서버를 한 번 거쳐 가게 하는 설정입니다. 수동은 공용 호스트로 쏩니다. 두 주소는 이름이 닮았을 뿐 다른 문이고 사이트가 자동 모드면 뒤쪽 문이 안 열립니다.
같은 문서에 한 줄이 더 있습니다.
Can I use automatic setup with a DNS-only domain (CNAME setup)? No … If you have a DNS-only domain, you will have to do a manual setup instead.
티스토리에 개인 도메인을 붙인 서브도메인 두 개가 정확히 DNS-only(Cloudflare 를 거치지 않고 주소만 연결해둔 상태)입니다. 그러니까 「이 호스트는 수동밖에 못 쓴다」와 「수동은 다른 주소로 쏜다」, 문서 두 줄을 나란히 놓으면 답이 이미 거기 있었습니다. 저는 이 둘을 다른 날 따로 읽어서 이어붙이지 못했습니다.
내가 틀렸던 지점 — 404 를 「실패」로 읽은 것

전환 뒤에 curl 로 같은 요청을 다시 쏴봤습니다. 여전히 404 였습니다.
같은 시각에 브라우저는 204 를 받고 있었고 대시보드에는 숫자가 들어오고 있었습니다.
| 재현 도구 | 전환 전 | 전환 후 | 이 도구로 말할 수 있는 것 |
|---|---|---|---|
curl 로 만든 POST | 404 | 404 | 합격/불합격 판정 불가 |
| 브라우저(네트워크 탭) | — | 204 | 실제 수집 여부 |
가짜 토큰 vs 진짜 토큰(curl) | 둘 다 404 | — | 차이 없음 → 토큰을 안 본다(유효) |
손으로 만든 요청 본문이 브라우저가 보내는 것과 어딘가 다릅니다. 어디가 다른지는 확인하지 못했습니다.
앞 글에서 제가 그 도구로 한 일은 두 가지인데 그중 하나만 살아남습니다.
- 살아남은 것: 가짜 토큰과 진짜 토큰의 응답이 같더라 → 토큰은 판정에 안 쓰인다. 이건 두 요청의 차이를 본 것이라 도구가 통째로 편향돼 있어도 결론이 유지됩니다.
- 죽은 것: 404 라는 절댓값을 「안 되고 있다」로 읽은 것. 전환 후에도 404 니까, 그 판독은 되고 있을 때도 404 를 돌려주는 판독이었습니다.
한 줄로 적으면 재현 도구는 비교축으로는 믿되 합격 판정으로는 믿지 않는다. 비교축에서 증거였던 같은 404 가 합격 판정에서는 잡음이었습니다.
순서를 틀리면 데이터가 빕니다

모드를 바꾸는 순간 자동 삽입이 멈춥니다. 그래서 ① 토큰을 채워 배포하고 → ② 대시보드에서 전환하는 순서로 갔습니다. 반대로 하면 배포가 끝날 때까지 apex(birchholt.com) 통계가 빕니다.
앞 글에서 이 순서 논증을 「아직 검증하지 못했다」고 적고 구멍을 둘 남겨뒀는데, 하나는 그대로 맞았고 하나는 풀렸습니다.
구멍 하나는 맞았습니다. 미리 배포해둔 수동 비콘도 전환 전까지는 똑같이 404 라 공백을 메우지는 못합니다. 그래서 이 순서의 효과는 「공백을 메운다」가 아니라 자동이 꺼지는 순간 수동이 이미 자리에 있게 만드는 것입니다. 결과는 같지만 근거가 다릅니다. 근거가 틀린 채로 맞은 답은 다음번에 틀립니다.
구멍 둘은 풀렸습니다. 겹치는 구간이 무해한지 몰라 beacon.min.js 에서 봤던
if(v&&"single"===v.load)return; 한 줄 — v 가 어디서 채워지는지 못 짚었다고 적었었습니다.
window.__cfBeacon 입니다. 먼저 실행된 비콘이 거기에 load='single' 을 세팅하고
두 번째 비콘은 그 값을 읽자마자 빠져나갑니다. 문서 근거도 둘 있었습니다.
Since only one JS snippet can be rendered and used per page, you cannot have multiple snippets on the same page. — Cloudflare Web Analytics FAQ
그리고 2021-05-28 변경 기록에도 비콘이 여러 개 도는 것을 막는 처리를 넣었다고 적혀 있습니다.
startsWith function replaced with indexOf function, which prevents rendering if multiple beacon scripts are loaded. — Cloudflare Web Analytics 변경 기록
가드가 지금도 배포본에 살아 있는지는 2026-09-21에 비콘 스크립트 원본을 다시 받아 확인했습니다.
방향까지 앞 글의 걱정이 맞았습니다. 제 템플릿에서 손으로 넣은 코드는 <head>,
자동 삽입은 </body> 직전이라 먼저 도는 쪽이 수동이고 빠져나가는 쪽이 자동입니다.
다만 실무적 함의는 제가 걱정하던 중복 집계에 없었습니다. 실제로는
먼저 실행된 쪽의 토큰이 이긴다는 것입니다. 두 태그의 토큰이 다르면 어느 사이트로
집계될지가 HTML 에 적힌 순서에 좌우됩니다. 제 경우는 같은 토큰이라 무해했는데
그렇게 설계한 적은 없으니 우연입니다.
전환 뒤에는 자동 삽입이 멈추므로 겹치는 구간 자체가 사라졌습니다. 두 태그가 실제로 한 번만 집계되는지 대시보드로 세어보지는 못했고 이제는 잴 수 없습니다.
잃은 것 하나 — 무결성 속성을 못 씁니다

수동 경로에는 SRI(받아온 스크립트가 바뀌지 않았는지 검사하는 무결성 속성)를 붙일 방법이 없습니다. 추측할 필요도 없이 공급자가 못박았습니다.
if you’re using the manually-embedded script approach, there is no current way to safely apply an
integrityattribute because we do not support version-pinning our beacon script — Cloudflare Web Analytics FAQ
앞 글에서 자동 삽입 태그를 뜯어봤을 때 버전이 박힌 URL + integrity 가 같이 있었습니다.
버전을 고정해주니까 파일이 그대로인지 대조하는 값을 붙일 수 있었던 겁니다. 수동은 버전 없는 주소라
같은 걸 할 수 없습니다. 억지로 붙이면 스크립트가 갱신되는 날 조용히 멈춥니다.
| 자동 설치 | 스니펫 설치 | |
|---|---|---|
| 스크립트 주소 | 버전 고정 | 버전 없음 |
integrity | 붙음 | 원리적으로 불가 |
type="module" | Cloudflare 가 부착 | 직접 부착 |
| 닿는 범위 | 프록시를 지나는 요청만 | HTML 에 넣은 곳 전부 |
그래서 제 사이트에서 무결성 속성이 남아 있는 자리는 제가 직접 만들어 배포하는 스타일시트 한 곳뿐입니다. 빌드가 파일 내용에서 해시를 뽑아 주소와 속성을 같은 순간에 함께 바꿔주니 손으로 맞출 게 없습니다. 「보안 속성은 많을수록 좋다」가 아니라 버전을 고정할 수 있는 곳에만 성립하는 속성입니다.
잃은 것 둘 — EU 방문자 제외가 사라집니다

전환 전 설정값은 Enable, excluding visitor data in the EU 였습니다.
제외는 자동 삽입에 딸린 옵션이었습니다. 넣는 주체가 우리로 바뀌면 걸릴 자리가 없어집니다.
전환 후에는 EU 방문자도 집계됩니다.
감수한 근거는 셋입니다.
- 이 계측은 쿠키도, 브라우저에 남는 저장값도, 방문자를 계속 따라다니는 식별자도 만들지 않습니다. 공급자 문서가 “does not store any data in the browser or access any storage data, such as cookies, localStorage, sessionStorage, IP address, or IndexedDB” 라고 적습니다 (RUM 비콘 문서)
- 한국어로만 쓰는 블로그라 EU 방문자 비중이 낮을 것으로 봤습니다. 대시보드로 따로 세어보지는 않았습니다.
- 선택의 여지가 없습니다. 위에 인용한 대로 DNS-only 호스트에는 자동 설치가 불가능합니다
모드는 대시보드에 등록한 사이트 항목 하나에 통째로 걸리는 설정이라 셋째가 결정적입니다. 세 호스트가 그 항목 하나를 공유하니 apex 만 자동으로 남기려면 항목을 쪼개야 합니다. 그러면 셋을 한 대시보드에서 보는 것을 잃습니다. 티스토리 쪽을 계측하겠다고 정한 순간 이 비용은 이미 결정돼 있었습니다.
확인하지 못한 것

여기서 한 번 더 틀렸습니다. 저는 「자동 삽입은 내 도메인에서 쏘는 것이라 광고 차단기를
덜 탄다」고 생각했습니다. 그렇다면 전환이 손실을 키우는 셈이라 비용 항목이 하나 더 늘어납니다.
그런데 차단기들이 쓰는 필터 목록 EasyPrivacy 원본을 받아 보면 도메인과 무관한 경로 규칙이
있습니다 — /cdn-cgi/rum? 과 /cdn-cgi/rum| 두 줄입니다. 자기 도메인으로 쏘든 공용 호스트로
쏘든 경로가 같으니 자동도 차단됩니다. 이 축에서는 두 모드에 우열이 없어서 전환의 비용이
아니었습니다.
필터 목록 EasyPrivacy 원본을 2026-09-21에
내려받아 확인했습니다(목록 버전 202609210628). 규칙이 목록 몇 번째 줄에 있는지는 갱신될 때마다 바뀝니다.
차단 비율은 확인하지 못했습니다. 공급자는 차단된다는 사실만 인정하고 어떤 수치도 낸 적이 없습니다. 검색으로 나오는 「광고 차단기 사용률」은 이 비콘의 차단률과 같은 값이 아닙니다.
대조군으로 삼으려던 쪽에서도 같은 착각을 했습니다. 저는 티스토리 자체 통계가 서버가 직접 세는 방식이라 차단되지 않는다고 적어뒀었는데, 페이지 원본을 받아 보면 티스토리도 방문자 브라우저에서 도는 추적 스크립트를 얹습니다. 게다가 위에 나온 그 필터 목록에 그 수집 호스트를 겨냥한 규칙이 여러 줄 있습니다. 한쪽만 손실이 0이라는 전제는 성립하지 않습니다.
두 계측이 같은 페이지에 동시에 붙어 있는 지금 같은 기간을 대조하면 두 값의 차이까지는 나옵니다. 다만 그 차이를 그대로 「제 블로그의 차단 손실률」로 읽을 수는 없습니다. 어느 쪽이 얼마나 덜 세는지를 따로 확인해야 합니다. 아직 안 했습니다. 한쪽을 접으면 대조군이 사라져 그마저도 못 잽니다.
티스토리 쪽 추적 스크립트가 브라우저에서 돈다는 것과, 그 수집 호스트가 같은 차단 목록에 올라 있다는 것은 2026-09-21에 페이지 원본과 목록 원본을 각각 내려받아 확인했습니다.
정리

- 404 가 항상 실패는 아닙니다. 되고 있는 상태에서도 제
curl은 404 를 돌려줬습니다 - 재현 도구는 두 요청의 차이를 볼 때만 믿습니다. 절댓값을 합격선으로 쓰면 안 됩니다
- 문서 두 줄이 각각은 무해한데 이어붙이면 원인이 됩니다. 「이 호스트는 수동만 가능」 + 「수동은 다른 주소로 쏜다」가 그랬습니다
- 무결성 속성은 버전을 고정할 수 있는 곳에서만 성립합니다
- 설정 하나를 바꾸면 그 설정에 딸려 있던 것들이 같이 움직입니다. 모드 전환의 비용은 모드 화면에 적혀 있지 않았습니다