트래픽의 30%가 봇이었다 — GA4가 거짓말을 한 6개월

GA4를 6개월 동안 잘못 읽고 있었습니다.

정확히는, GA4가 보여주는 숫자가 잘못된 건 아니었습니다. 제가 그 숫자를 사람의 방문 횟수로 받아들였던 것이 잘못이었습니다. 운영 중인 사이트들의 전체 트래픽 중 30~40%가 봇이었다는 사실은, 발견하기 전까지 6개월간 측정값을 부풀려 놓고 있었습니다.

처음 이상하다고 느낀 건 어떤 사이트의 직접 유입 비율이 너무 높다는 점에서였습니다. 검색도, 추천도, 소셜도 거의 없는 사이트인데 desktop direct 트래픽이 매일 일정한 양으로 들어오고 있었습니다. 평소라면 이 직접 유입을 두고 "북마크 재방문" 같은 좋은 신호라고 해석했을 텐데, 사이트 자체가 신규였습니다. 북마크할 사람이 없었습니다.

지역 분포를 들여다보았습니다. 미국, 네덜란드, 세이셸. 한국 SMB 도구 사이트인데 그쪽 트래픽이 두텁게 깔려 있었습니다. ISP 차원에서 한 번 더 들여다보았습니다. 일반 통신사가 아니라 데이터센터였습니다. desktop direct 시그니처로, 일정한 페이스로, 매일 같은 양이 들어오고 있었습니다.

거기까지 확인한 시점에 깨달았습니다. 이건 사람이 아니라 크롤러였습니다. 사이트마다 비율은 달랐지만, 운영 중인 사이트 전체 평균으로 30~40%가 이 데이터센터 봇이었습니다. 어떤 사이트는 절반 가까이였습니다.

발견 자체는 새로울 게 없습니다. 봇 트래픽이 GA4에 잡힌다는 건 알려진 이야기입니다. 다만 그것이 제 사이트들에서 어느 정도 비율인가를 직접 확인한 적이 없었기 때문에, 모든 분석을 "GA4 raw 숫자 = 사람의 방문" 이라는 전제로 6개월간 쌓아 올린 것이 문제였습니다.

다시 보니 그동안 내렸던 결정 몇 가지가 의심스러워졌습니다. "방문은 들어오는데 전환이 안 된다" 고 판단해서 카피를 고치고 CTA 위치를 옮겼던 사이트가 있었는데, 그 방문 자체가 30~40% 줄어든다고 가정하면 전환율은 사실 나쁘지 않았던 사이트일 수도 있었습니다.

이 시점에서 두 가지 선택지가 있었습니다.

하나는 CloudFront나 WAF 차원에서 봇을 차단하는 것. 들어오기 전에 막아버리면 데이터가 깨끗해집니다. 다른 하나는 들어오는 건 그대로 두고, 분석할 때만 제외하는 것. 운영 중인 사이트가 100개가 넘는 상황에서 모든 사이트에 일관된 차단 규칙을 적용하고 유지하는 비용을 생각하면, 후자가 합리적이었습니다.

그래서 분석 스크립트에 --no-bots flag 와 withBotExclusion() 헬퍼를 추가했습니다. 데이터센터 ISP 리스트와 desktop direct 시그니처를 기준으로 봇 의심 세션을 제외한 뒤에야 진짜 트래픽 곡선을 봅니다. 봇은 그냥 들어오게 둡니다. 인프라 비용은 어차피 작은 정적 사이트라 무시할 만한 수준입니다.

봇을 제외하고 다시 본 데이터는, 일부 사이트에서는 더 안 좋게 보였고 일부 사이트에서는 오히려 더 깨끗하게 보였습니다. 트래픽 총량은 줄었지만 그 안의 사람 행동 패턴은 또렷해졌습니다.

지금 와서 생각하면 가장 큰 손해는 6개월이라는 시간이었습니다. 같은 실수를 두 번 하지 않으려면, 새 사이트를 띄울 때 첫 주에 직접 유입 비율 / 지역 분포 / ISP 분포 세 가지를 먼저 보는 습관이 필요하다는 것이 이번 사건의 한 줄 교훈에 가깝습니다.

데이터는 거짓말하지 않는다고 합니다. 맞는 말이지만, 그 데이터를 무엇이라고 부르고 있는지는 매번 확인해야 합니다.