본문으로 건너뛰기
블로그로 돌아가기
디지털 마케팅 분석 입문

광고 클릭 수와 사이트 방문 수가 다른 이유: 추적 링크와 MMP로 사이트 밖 재기

GA4는 사이트에 도착한 사람부터 센다. 링크를 눌렀지만 도착 전에 사라진 사람은 어느 리포트에도 남지 않는다. 그 구간을 재려면 링크가 목적지로 바로 가지 않고 내가 통제하는 서버를 한 번 들르게 해야 하며, 추적 링크와 MMP가 하는 일이 정확히 그것이다.

26분 소요디지털 마케팅 분석 입문
추적 링크MMPAirbridge오프페이지 측정클릭 추적리다이렉트 추적click_id어트리뷰션
광고 클릭 수와 사이트 방문 수가 다른 이유: 추적 링크와 MMP로 사이트 밖 재기

대상: GA4·GTM은 쓰는데 사이트 밖은 안 재 본 마케터  ·  형식: 설명 가이드  ·  2026-08-03

핵심 요약 · TL;DR

Q. 광고 플랫폼이 보고한 클릭 수와 GA4 세션 수는 왜 다를까?

GA4는 사이트에 도착한 사람부터 센다. 링크를 눌렀지만 도착 전에 사라진 사람은 어느 리포트에도 남지 않는다. 그 구간을 재려면 링크가 목적지로 바로 가지 않고 내가 통제하는 서버를 한 번 들르게 해야 하며, 추적 링크와 MMP가 하는 일이 정확히 그것이다.

오늘 바로 쓸 핵심 3줄

  • 광고 플랫폼 클릭과 GA4 세션을 같은 기간으로 나란히 놓고 차이율부터 재라
  • 앱 설치가 퍼널에 없다면 MMP 대신 리다이렉터 한 대로 충분하다
  • 계측 못 하는 오운드 미디어는 입구·출구 링크를 같은 추적 도메인으로 걸어 이어라

GA4는 도착한 사람부터 센다

광고 관리자에서 클릭 수를 본다. 같은 기간 GA4에서 세션 수를 본다. 두 숫자가 안 맞는다. 거의 모든 계정에서 벌어지는 일이고, 처음 보는 사람은 둘 중 하나가 고장 났다고 의심한다.

둘 다 정상이다. 애초에 재는 대상이 다르니까.

GA4는 내 사이트에 심어 둔 태그가 실행돼야 데이터를 만든다. 사람이 도착하고, 페이지가 열리고, 스크립트가 돌아간 다음부터 존재하는 도구라는 뜻이다. 그 앞에서 벌어진 일은 관측 범위 밖이라 리포트에 빈칸으로도 안 남는다.

그런데 그 사이에는 생각보다 많은 일이 있다.

  • 눌렀는데 랜딩이 느려서 뒤로 갔다
  • 카카오톡이나 인스타그램의 인앱 브라우저가 링크를 제대로 못 열었다
  • 리다이렉트가 한 번 더 걸리면서 utm_source 같은 꼬리표가 떨어졌다
  • 광고 플랫폼이 클릭으로 세는 기준과 GA4가 세션으로 세는 기준이 애초에 다르다

넷은 대응이 전부 다르다. 첫째는 랜딩 속도 문제, 둘째는 링크 형식 문제, 셋째는 태깅 문제, 넷째는 그냥 정상. 그런데 GA4만 보면 넷이 구분되지 않는다. 전부 세션이 생각보다 적다는 한 덩어리로 뭉쳐질 뿐.

측정은 여섯 층인데, 우리는 세 번째 층부터 켠다

이 문제를 제대로 보려면 측정을 층으로 갈라 놓는 게 편하지. 광고가 노출되고 나서 매출이 잡히기까지 사람이 지나는 문은 여섯 개다.

측정의 여섯 층 GA4·GTM으로 하는 일 대부분 L0 노출 광고 플랫폼 서치콘솔 L1 링크 클릭 재는 주체 없음 L2 랜딩 진입 GA4 · UTM L3 사이트 행동 GTM · dataLayer L4 전환 픽셀 · 서버 L5 오프라인 CRM · 콜 여기가 빈칸이다 광고 플랫폼은 자기가 집행한 클릭만 안다. 카톡 공지·유튜브 설명란은 아무도 안 센다.

GA4와 GTM으로 하는 일은 대부분 L2부터 L4 사이에 있다. L0은 광고 플랫폼과 서치콘솔이 각자 보고해 주고, L5는 CRM에서 따로 돈다. 아무도 세지 않는 층은 L1.

층 모델 자체를 처음 본다면 마케팅 측정 설계를 다섯 층으로 진단하는 글을 먼저 보는 게 낫다. 이 글은 그 위에 사이트 바깥 한 층을 더 붙이는 이야기.

빈칸이 왜 하필 L1일까? 링크를 눌렀다는 사실을 기록할 주체가 아무 데도 없어서. 광고 플랫폼은 자기가 집행한 광고의 클릭만 알고, 카카오톡 공지나 유튜브 설명란이나 제휴 블로그에 붙인 링크는 누구의 관측 대상도 아니다.

그래서 그 링크들은 다크 퍼널로 흘러 들어간다. 성과가 없어서 안 보이는 게 아니라, 보는 장치를 안 달아서 안 보이는 것.

링크를 서버에 한 번 들르게 하면 벌어지는 일

L1을 재는 방법은 원리상 하나뿐. 링크를 목적지로 곧장 보내지 말고, 내가 통제하는 서버를 한 번 들르게 한다.

추적 링크가 하는 일 사용자가 누른다 카톡 공지 · 유튜브 설명란 내 추적 서버 시각 · IP · User-Agent · 리퍼러 여기서 기록이 남는다 목적지 랜딩 여기서부터 GA4가 켜진다 요청 302 응답 기록이 브라우저가 아니라 서버에 남는다 쿠키가 차단돼도, 자바스크립트가 안 돌아도, 사용자가 도착 전에 이탈해도 클릭 기록은 이미 남아 있다. GA4가 못 보는 구간이 여기서 보이는 이유. 사용자 체감 지연은 수십 밀리초 수준.

단축 URL이 클릭 수를 세는 원리도, MMP가 어트리뷰션을 시작하는 지점도 똑같이 여기다.

들르는 순간 서버는 요청 하나를 받는데, 거기엔 시각과 IP, 브라우저 종류, 어디서 눌렀는지(리퍼러)가 실려 있다. 서버는 그걸 기록하고 302라는 응답으로 진짜 목적지를 알려준다. 브라우저는 목적지로 이동한다. 사용자 눈에는 그냥 링크가 열린 것.

여기서 결정적인 건 기록이 브라우저가 아니라 서버에 남는다는 점. 쿠키를 차단한 사람도, 광고 차단기를 켠 사람도, 도착 전에 뒤로 가기를 누른 사람도 클릭 자체는 이미 세어졌다. GA4가 구조적으로 못 보는 구간이 여기서 보인다.

함정. 리다이렉트를 한 단계 끼우면 UTM 꼬리표가 떨어질 수 있다. 목적지 URL에 이미 붙어 있던 파라미터를 서버가 그대로 실어 보내는지 반드시 확인해야 한다. 이 사고의 유형과 방어법은 UTM 유실 방지 글에 정리해 뒀다.

MMP는 그 위에 무엇을 더 얹나

리다이렉트로 클릭을 세는 것까지는 단축 URL 서비스도 한다. MMP(Mobile Measurement Partner)는 그 위에 을 얹는다. Airbridge, AppsFlyer, Adjust, Branch가 같은 시장의 제품들.

말로 푸는 것보다 구조를 보는 게 빠르지. Airbridge 추적 링크는 이런 모양.

추적 링크 뜯어보기 https:// abr.ge / @{app_name} / {channel_name} ? {parameters} 기본 도메인 자체 도메인으로 바꿀 수 있다(커스텀 도메인) 등록한 앱 대시보드에 만든 앱 식별자 채널 이 링크가 실린 매체. 성과가 이 단위로 갈린다 파라미터 캠페인 정보 · 딥링크 · 터치포인트 식별자 터치포인트에는 ad_type 이 붙어 노출(impression) · 클릭(click) · 서버 간 클릭(S2S click)을 구분한다.

클릭 하나가 어느 채널의 어느 캠페인에서 왔는지, 서버가 이미 아는 상태로 사용자가 도착한다.

앱이 있으면 여기서 진짜 힘이 생긴다. 클릭에서 스토어로, 스토어에서 설치로, 설치에서 첫 실행으로 이어지는 구간은 브라우저 쿠키가 절대 못 잇는다. 브라우저와 앱은 서로 다른 상자라서 그렇지. MMP는 그 상자 두 개를 잇는 걸 본업으로 삼는다.

웹에서는 deeplink_url로 앱이 깔린 사람을 앱 화면으로 보내고, fallback_ 계열 파라미터로 안 깔린 사람을 웹이나 스토어로 나눠 보낸다. 웹만 볼 거라면 Web SDK를 설치하는데, npm 모듈로도 되고 GTM으로도 된다. 추적 링크에 실린 UTM 값을 자동으로 저장해서 캠페인 출처를 잡아준다.

솔직히 말하면. 나는 Airbridge를 운영해 본 적이 없다. 이 절의 링크 구조·파라미터·과금 설명은 전부 공식 문서에서 확인한 것이고, 대시보드에서 숫자가 실제로 어떻게 보이는지에 대한 감각은 이 글에 없다. 도입을 검토 중이라면 구조는 여기서 잡고, 운영 감각은 써 본 사람에게 물어보는 게 맞다.

앱이 있나 없나에서 길이 갈린다

MMP를 살지 말지는 기능 비교표로 안 갈린다. 갈리는 건 질문 하나.

브라우저가 혼자서는 못 잇는 구간이 내 퍼널에 있나?

앱 설치가 퍼널에 있으면 그 구간이 있다. 광고를 클릭한 브라우저와 앱을 처음 켠 사람을 이어 줄 방법이 달리 없고, 이건 MMP의 존재 이유라 마땅한 대체재가 없다.

웹에서 상담 신청이나 리드만 받는다면 그 구간이 없다. 클릭에서 랜딩으로, 랜딩에서 폼 제출로 가는 길이 전부 브라우저 안에서, 대개 같은 도메인 안에서 끝난다. UTM과 GA4가 이미 덮고 있는 영역.

주황색 경로 하나가 갈림길에서 두 갈래로 나뉘어, 왼쪽은 여러 층으로 쌓인 복잡한 구조물로 오르고 오른쪽은 짧고 평평하게 단순한 블록으로 이어지는 평면 벡터 일러스트

이미지: 두 길의 차이는 우열이 아니라 규모다. 앱이 없는데 큰 쪽을 고르면 안 쓰는 기능값을 낸다.

과금 구조도 이 판단을 거드는 쪽. Airbridge 요금은 앱을 한 번이라도 쓴 월 활성 사용자 수를 기준으로 매겨지고, 오가닉 트래픽과 웹 트래픽은 과금 대상이 아니다. 웹만 있는 서비스가 웹만 재려고 MMP를 도입하면, 도구의 무게중심과 내 문제가 어긋난 채로 쓰게 된다는 뜻이다.

내 상황L1을 어떻게 재나이유
앱 설치가 퍼널에 있다MMP브라우저에서 앱으로 넘어가는 구간은 대체재가 사실상 없다
웹만, 채널 다수, 링크 만드는 사람도 여럿MMP 또는 자체 리다이렉터진짜 이유는 측정이 아니라 링크 발급 거버넌스다
웹만, 채널 소수, 링크를 내가 다 만든다자체 리다이렉터필요한 건 클릭 로그와 조인키뿐이다
클릭 수만 알면 된다단축 URL 서비스전환까지 안 이을 거면 더 살 이유가 없다

남의 플랫폼을 지날 때, 무엇이 끊기고 무엇이 안 끊기나

여기가 이 주제에서 오해가 제일 많은 지점이고, 두 경우를 갈라야 한다. 그런데 가르는 기준이 흔히 생각하는 것과 다르다.

가로로 뻗은 통로의 가운데가 속이 안 보이는 남색 덩어리로 막혀 있고, 그 양쪽 끝에 똑같이 생긴 주황색 관문이 하나씩 서 있어 주황색 빛줄기가 왼쪽 관문으로 들어갔다가 오른쪽 관문으로 다시 나오는 평면 벡터 일러스트

이미지: 가운데는 못 본다. 대신 양쪽 끝에 똑같은 관문을 세우면, 들어간 빛과 나온 빛이 같은 빛이라는 건 알 수 있다.

기준은 소유가 아니라 링크를 심을 수 있느냐다

갈리는 기준은 "그 사이트가 내 것이냐"가 아니라 그 사이트를 드나드는 링크를 내가 심을 수 있느냐다.

남이 쓴 글, 내가 손댈 수 없는 제3자 페이지라면 정말로 끊긴다. 들어간 것까지는 알아도 거기서 나오는 링크를 내가 만들 수 없으니 뒤를 이을 고리가 없다.

그런데 실무에서 훨씬 흔한 건 다른 쪽이다. 우리가 운영하는 네이버 블로그, 우리 유튜브 채널, 우리 카카오 채널. 플랫폼은 남의 것이지만 콘텐츠와 그 안의 링크는 내 것인 경우다. 흔히 오운드 미디어라고 부르는데, 이때는 안쪽을 못 봐도 입구와 출구가 둘 다 내 손에 있다.

링크를 심을 수 있느냐가 가른다 내가 운영하는 오운드 미디어 카톡 공지 외부 채널 go.example.com/a 쿠키 심음 우리 네이버 블로그 안쪽은 못 본다 go.example.com/b 쿠키 다시 읽음 우리 사이트 전환까지 같은 도메인 = 같은 쿠키 두 번 다 사용자가 직접 이동해 온 최상위 내비게이션이라, 서드파티 쿠키 차단과는 무관하다. 링크를 못 심는 제3자 페이지 카톡 공지 외부 채널 go.example.com/a 쿠키 심음 남이 쓴 글 링크를 못 심는다 출구에 체크포인트를 못 세운다. 여기서부터는 정말로 끊긴다.

플랫폼이 남의 것이냐가 아니라, 나가는 링크를 내가 만들 수 있느냐가 기준이다.

블로그 안에서 뭘 했는지를 알 필요가 없다. 들어갔다가 나왔다는 사실만 이으면 된다.

왜 쿠키가 다시 실리나

여기서 "서드파티 쿠키가 다 막혔다는데 그게 되나" 하는 의문이 생길 만하다. 되는 이유는 이게 서드파티 쿠키가 아니어서다.

같은 쿠키, 다른 맥락 끼워 넣어진 맥락 = 서드파티 blog.someplatform.com 남의 페이지 본문 내 픽셀·iframe 끼워 넣어져 있다 브라우저가 막는다 주소창 주인과 쿠키 주인이 다르다 직접 건너온 맥락 = 퍼스트파티 go.example.com 창 전체가 내 도메인이다 그대로 실린다 주소창 주인 = 쿠키 주인. 차단 대상이 아니다

차단 여부를 가르는 건 쿠키의 종류가 아니라 그 순간 주소창의 주인이 누구냐다.

첫 번째 링크를 눌러 go.example.com/a에 닿는 순간, 서버가 방문자 번호를 하나 발급해 그 도메인의 쿠키로 심고 클릭을 기록한다. 사용자는 블로그로 넘어갈 뿐이고.

그 사람이 블로그 안의 두 번째 링크를 눌러 go.example.com/b로 오면, 브라우저는 같은 도메인이니 아까 심은 쿠키를 그대로 다시 보낸다. 서버 입장에선 같은 방문자 번호가 두 번 찍힌 것이라, 두 클릭이 한 사람으로 묶이는 것.

두 번 다 사용자가 링크를 눌러 주소창째로 건너온 이동이라는 게 핵심이다. 브라우저가 차단하는 서드파티 쿠키는 남의 페이지 안에 iframe이나 픽셀로 끼워 넣어져 읽히는 쿠키를 말한다. 내 도메인으로 직접 건너온 경우는 그 얘기가 아니지. 그래서 네이버 블로그에 추적 코드를 심을 필요가 없다. 들고 나는 링크만 내 도메인을 거치면 그만.

전환까지 한 줄로 잇기

우리 사이트의 전환까지 이으려면 두 방법이 있다. 두 번째 링크가 목적지로 보낼 때 방문자 번호를 URL에 실어 보내거나, 추적 도메인과 사이트가 같은 상위 도메인 아래라면 쿠키를 공유하면 된다.

Set-Cookie: visitor_id=abc123;
            Domain=.example.com;   // go.example.com 과 www.example.com 이 같이 읽는다
            Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=15552000

그러면 기록은 두 군데에 나뉘어 쌓이는데, 같은 방문자 번호가 양쪽을 관통한다.

기록은 두 군데, 축은 하나 추적 서버 go.example.com 사이트 밖에서 벌어진 일을 여기서 잡는다 external_link_click owned_media_enter owned_media_exit 우리 사이트 GA4 · dataLayer 도착 이후를 잡는다 landing_view submit_db visitor_id 분석 창고 한 사람으로 합쳐짐 같은 번호가 다섯 지점에 찍히니 구간마다 걸린 시간까지 남는다.

사이트 밖 세 이벤트는 추적 서버가, 도착 이후 두 이벤트는 GA4가 잡는다. 둘을 붙이는 건 방문자 번호 하나뿐이다.

visitor abc123
  external_link_click   source=kakao_notice
  owned_media_enter     media=naver_blog     content_id=post_001
  owned_media_exit      media=naver_blog     link_id=main_cta
  landing_view          page=/internet
  submit_db             value=...

단계 사이의 시간 간격까지 남으니, 공지를 본 사람이 블로그를 거쳐 며칠 만에 돌아오는지도 보이고. 이 두 이벤트(owned_media_enter·owned_media_exit)는 그냥 만들어 붙이는 게 아니라 이벤트 체계 안에 정식으로 자리를 잡아야 하는데, 그 설계는 이벤트 택소노미 편에서 따로 다룬다.

이 방식이 조용히 깨지는 세 지점

다만 100%는 아니고, 깨지는 방식이 고약하다. 오류를 내며 멈추는 게 아니라 그냥 다른 사람으로 잡힌다.

연결이 끊기는 세 경우 1. 브라우저가 바뀐다 카톡 인앱 쿠키함 A 네이버 앱 쿠키함 B 같은 사람인데 저장소가 다르다. 방문자 번호가 둘이 된다. 한국 실무에서 제일 크다 메신저에서 열고 앱으로 넘어가는 흐름 2. 도메인이 분류된다 브라우저가 최상위 리다이렉트 횟수를 센다. 분류됨 쿠키가 SameSite=Strict 다시 쓰일 수 있다. 외부에서 넘어올 때 안 실린다 30일 무상호작용이면 데이터도 삭제 3. 평범한 것들 시크릿 모드 쿠키 삭제 폰에서 보고 PC에서 재방문 어떤 방식으로도 못 막는다. 그래서 연결률은 하한선이다

셋 다 오류를 내지 않는다. 조용히 다른 사람으로 세어질 뿐이라, 리포트만 보면 눈치채기 어렵다.

첫째, 브라우저가 바뀌는 경우. 한국에서 이게 제일 크다. 카카오톡 인앱 브라우저에서 첫 링크를 누르고, 네이버 블로그가 열리면서 네이버 앱으로 전환되고, 거기서 두 번째 링크를 누르면 쿠키 저장소가 아예 다르다. 같은 사람인데 방문자 번호가 둘이 되는 것.

둘째, 브라우저의 바운스 트래킹 대응. 이 구조는 리다이렉트만 하고 지나가는 도메인을 쓰는데, 브라우저들이 정확히 그 패턴을 겨냥한 장치를 갖고 있다. Safari의 ITP는 최상위 리다이렉트 횟수를 세어 도메인을 분류하고, 바운스 트래킹으로 분류되면 그 도메인의 쿠키를 SameSite=Strict로 다시 쓸 수 있다. Strict가 되면 외부 사이트에서 넘어오는 이동에 쿠키가 실리지 않으므로, 블로그에서 두 번째 링크를 눌러 오는 바로 그 경로가 끊긴다. 분류된 도메인이 30일간 퍼스트파티 상호작용을 못 받으면 저장된 데이터도 지워진다.

셋째, 평범한 것들. 시크릿 모드, 쿠키 삭제, 폰에서 보고 PC에서 다시 오는 경우. 이건 어떤 방식으로도 못 막지.

그래서 이 숫자는 하한선으로 읽는다. 이어진 비율이 60%로 나왔다면 "40%가 이탈했다"가 아니라 "최소 60%는 이어졌고, 나머지는 이어졌는지 모른다"가 맞는 해석이다. 리포트에 이걸 안 적으면 다음 사람이 40%를 이탈률로 읽고 콘텐츠를 고치러 간다. 그리고 분류 기반 차단은 어느 날 갑자기 비율을 떨어뜨리므로, 연결률 자체를 시계열로 지켜보는 게 낫다. 급락하면 콘텐츠가 아니라 도메인이 분류됐다는 신호일 수 있다.

그래서 손에 남는 것

무엇이 남고 무엇이 안 남는지 추리면 이렇다.

알 수 있다알 수 없다
공지 링크가 몇 번 눌렸나블로그를 몇 분 읽고 어디까지 스크롤했나
어느 게시물로 보냈나블로그 안에서 어떤 문단이 먹혔나
그 안의 어떤 CTA가 눌렸나브라우저가 바뀐 사람이 같은 사람인지
같은 방문자가 우리 사이트에 도착했나쿠키를 지운 사람의 앞 여정
도착 후 전환했나, 단계별로 며칠 걸렸나링크를 안 거치고 검색으로 온 사람의 경로

오른쪽 칸은 대부분 애초에 알 필요가 없던 것. 목적이 "블로그를 잘 읽었나"가 아니라 "측정 못 하는 구간을 통과했다는 사실과 그 앞뒤를 잇는 것"이었으니까.

정리하면 이 시스템은 클릭 카운터가 아니다. 계측할 수 없는 오운드 미디어의 입구와 출구에 체크포인트를 박는 방식이고, 네이버 블로그든 유튜브 설명란이든 카카오 채널이든 제휴 랜딩이든 같은 패턴으로 확장된다. 안을 못 보는 건 받아들이고, 통과했다는 사실을 잡는 것.

다만 이렇게 이어 붙인 경로를 개인 단위 여정이라고 부를 때는 위의 한계를 같이 적어야 한다. 리포트에 "고객 여정"이라고만 쓰면 팀은 없는 정밀도를 믿고, 나중에 그 숫자로 예산을 옮긴다. 여기가 어트리뷰션 모델을 읽을 때와 똑같은 함정이다.

MMP 없이 오프페이지를 재는 법

앱이 없어서 MMP가 과하다면, L1을 직접 만들 수 있다. 필요한 건 서브도메인 하나와 리다이렉트 한 대.

직접 만드는 L1 외부 채널 카톡 · 유튜브 · 제휴 go.example.com 클릭 로그 기록 click_id 발급 랜딩 페이지 GA4가 click_id를 실어 보냄 BigQuery 두 테이블 조인 클릭 테이블도 여기로 적재된다 핵심은 조인키 하나다 클릭에 발급한 click_id가 목적지까지 실려 가면, 클릭 기록과 전환 기록이 같은 키를 공유한다. 그 순간 두 테이블이 붙는다. MMP가 파는 기능의 웹 버전이고, 원리는 똑같다.

클릭 로그와 전환 로그를 잇는 건 도구가 아니라 조인키.

코드처럼 보여도 겁먹을 필요는 없다. 하는 일은 다섯 줄로 요약되지. 주소를 받고, 진짜 목적지를 찾고, 클릭마다 고유 번호를 하나 붙이고, 기록을 남기고, 목적지로 보낸다.

// Cloudflare Workers, go.example.com/:key
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const key = url.pathname.slice(1);
    if (!key) return new Response('Not found', { status: 404 });

    const target = await env.LINKS.get(key);      // key 로 진짜 목적지를 찾는다
    if (!target) return new Response('Not found', { status: 404 });

    const clickId = crypto.randomUUID();          // 클릭마다 고유 번호
    const dest = new URL(target);
    dest.searchParams.set('click_id', clickId);   // 목적지까지 실어 보낸다

    env.CLICKS.writeDataPoint({                   // 기록은 응답을 막지 않는다
      blobs: [key,
              request.headers.get('referer') ?? '',
              request.headers.get('user-agent') ?? '',
              request.cf?.country ?? '',
              clickId],
      doubles: [1],
      indexes: [key],
    });

    return Response.redirect(dest.toString(), 302);
  },
};

핵심은 click_id를 목적지 URL에 붙이는 한 줄. 그 값이 붙은 채로 도착하면 랜딩에서 그걸 주워 GA4 이벤트 파라미터나 폼 히든 필드에 실을 수 있다. 클릭 기록과 전환 기록이 같은 키를 공유하는 순간, 두 테이블이 조인된다.

이 발상 자체는 새로운 게 아니다. 구글의 gclid와 메타의 fbclid가 하는 일이 정확히 이거고, 서버사이드 전환을 보낼 때 그 값을 같이 실어 보내는 이유도 같다. 원리는 클릭ID와 서버사이드 전환을 다룬 글에 정리해 뒀다. 지금 만든 건 그 구조를 내 채널에 대고 직접 세운 것.

적재해 두면 처음의 질문에 숫자로 답할 수 있다.

-- 예시 쿼리다. 아래 구조로 짜면 된다는 뜻이고, 실행 결과가 아니다.
SELECT
  c.link_key,
  COUNT(DISTINCT c.click_id)                   AS clicks,
  COUNT(DISTINCT s.click_id)                   AS arrived,
  SAFE_DIVIDE(COUNT(DISTINCT s.click_id),
              COUNT(DISTINCT c.click_id))      AS arrival_rate
FROM  `analytics.link_clicks`   AS c
LEFT JOIN `analytics.sessions`  AS s USING (click_id)
GROUP BY link_key
ORDER BY clicks DESC

arrival_rate가 이 글 첫 문단의 답. 클릭은 셌는데 도착이 안 됐다는 사실 자체가 데이터가 되고, 링크별로 나오니 어떤 채널의 어떤 링크가 새는지도 보인다. 인앱 브라우저에서 발급된 링크만 유독 낮게 나오는 식으로 원인이 드러난다.

남의 무료 서비스에 링크 인프라를 얹는 위험. Firebase Dynamic Links는 2025년 8월 25일 종료됐고, 그때까지 발급된 링크는 커스텀 도메인이든 page.link든 전부 404를 반환한다. 미리 내보내지 않은 분석 데이터도 회수할 수 없다. 링크는 한 번 배포되면 유튜브 설명란과 오래된 게시글에 몇 년씩 남는다는 걸 생각하면, 그 도메인을 누가 통제하느냐는 측정 문제가 아니라 자산 문제다.

직접 만들 것이냐 사올 것이냐는 규모에서 갈린다. 링크 종류가 수십 개가 되고 발급하는 사람이 여럿이 되면 관리 화면과 권한이 필요해지고, 그때부터 SaaS가 값을 하기 시작한다. 반대로 링크가 열 몇 개고 내가 다 만든다면 위 코드와 키-값 저장소 하나로 반나절이면 선다.

진짜 비용은 만드는 쪽이 아니다. 6개월 뒤에도 링크 이름 규칙이 안 무너지게 지키는 일이 비용이다. 그건 도구가 아니라 컨벤션 문제고, 다음 편에서 UTM을 손 가는 대로 붙였을 때 6개월 뒤에 벌어지는 일로 따로 다룬다.

오늘 30분이면 내 계정에서 확인할 수 있다

도구를 사기 전에 할 일이 있다. 내 격차가 얼마인지부터 재는 것. 격차가 3%면 아무것도 안 해도 되고, 30%면 도구 이전에 랜딩부터 고쳐야 한다.

오프페이지 측정, 5단계 체크리스트
  1. 격차 측정: 광고 플랫폼 클릭 수와 GA4 세션 수를 같은 기간·같은 캠페인으로 나란히 놓아라. 차이가 몇 퍼센트인가?
  2. 원인 분리: 격차가 크면 인앱 브라우저 비중과 랜딩 로딩 속도부터 봐라. 대개 이 둘이 대부분을 설명한다.
  3. 오프페이지 목록화: 광고가 아닌 곳에 붙인 링크를 전부 적어라. 카톡 공지, 유튜브 설명란, 이메일, 제휴 게시글. 몇 개가 아무 기록도 안 남기고 있나?
  4. 갈림길 판정: 앱 설치가 퍼널에 있나? 있으면 MMP를 검토하고, 없으면 리다이렉터 한 대로 충분하다.
  5. 조인키 확보: 어떤 방식을 택하든 클릭에 고유 번호를 발급하고 목적지까지 실어 보내라. 그게 없으면 어떤 도구를 사도 두 테이블은 안 붙는다.

그래도 하나만 챙긴다면, 이것이다.

재지 않은 구간은 성과가 없는 게 아니라, 성과를 모르는 것이다.

이 글은 디지털 마케팅 분석 입문 시리즈의 심화편. 전체 지도는 측정 설계를 다섯 층으로 진단하는 글에 있고, 도착 이후의 이야기는 UTM 파라미터 기초쿠키·세션·이벤트 기초에서 이어진다. 다음 편은 사이트 밖 노출을 채널별로 재는 법이고, 그중 오가닉을 실제로 재 본 기록은 SERP 슬롯 380개 실측 편에 있다.

근거·출처

나는 Airbridge를 직접 운영해 본 적이 없다. 이 글의 도구 설명은 전부 공식 문서를 확인해 쓴 것이고, 대시보드 실사용 감각은 담기지 않았다. 리다이렉터 코드는 동작 원리를 보이기 위한 최소 예시이며, 운영에는 봇 필터와 재시도 처리, 개인정보 보관 기간 정책이 더 필요하다. BigQuery 쿼리는 구조를 보이기 위한 예시이고 실행 결과가 아니다. 오운드 미디어 체크포인트의 연결률은 브라우저 정책에 따라 달라지므로, 내 채널에서 실제로 몇 퍼센트가 이어지는지는 직접 재 봐야 안다.

이 글이 도움이 되었다면 공유해주세요

최신 인사이트

관련 프로젝트

새 글을 이메일로 받아보세요

마케팅, 분석, 개발 인사이트를 정리해서 보내드려요.