BuddyStudy AdServer는 누구에게 어떤 광고를 보여줄까
광고를 많이 보여주는 것이 목표가 아니다. 지금 이 사용자에게 필요한 정보를 고르는 것이 목표다.
1. 어떤 지면에 광고를 전달할 것인가
광고 서버가 가장 먼저 결정해야 하는 것은 광고를 누구에게 보낼지가 아니라, 어느 화면의 어떤 위치에 광고를 넣을지다. 이 위치를 광고 지면이라고 한다.
BuddyStudy에서는 Public View의 메인 포스팅 목록을 첫 번째 광고 지면으로 정했다. 사용자가 메인 포스팅 목록을 처음 조회하면 서버는 일반 포스팅 목록을 불러오면서, 이 지면에 현재 사용자에게 전달할 수 있는 광고가 있는지 함께 확인한다. 적합한 광고가 있으면 정해진 위치에 광고를 포함하고, 없다면 일반 포스팅 목록만 응답한다.
모든 사용자에게 광고를 무작위로 전달하는 방식은 구현은 간단하지만 효과가 낮다. 관심 없는 사용자에게도 광고가 노출되면서 한정된 노출 기회와 예산이 소모되고, 실제 노출 수가 늘더라도 클릭률과 전환율은 낮아질 수 있다. 따라서 지면의 성격과 사용자 조건에 맞는 적합한 광고를 골라 전달하는 과정은 필수다.
여기서 적합한 광고는 다음 조건을 만족해야 한다.
- Public View 지면에 노출할 수 있다.
- 현재 사용자가 타기팅 조건에 포함된다.
- 광고 기간과 예산이 남아 있다.
- 같은 사용자에게 과도하게 노출되지 않았다.
- 사용자가 관심 없음으로 표시하지 않았다.
하지만 타기팅 조건을 통과했다는 이유만으로 좋은 광고가 되는 것은 아니다. 광고를 실제로 전달한 뒤에는 어떤 광고가 사용자의 반응을 얻었는지 계속 관찰하고, 그 결과를 다음 광고 선택에 반영해야 한다. 이를 위해 같은 지면과 사용자 그룹을 대상으로 하는 광고끼리 경쟁시킨다.
광고 서버는 다음 지표를 광고별로 집계한다.
- 전달 수: 서버가 광고를 선택해 응답에 포함한 횟수
- 실제 노출 수: 사용자의 화면에 광고가 실제로 보인 횟수
- 클릭률: 실제 노출 중 클릭으로 이어진 비율
- 전환율: 클릭 이후 가입이나 구매 같은 목표 행동으로 이어진 비율
클릭률은 광고가 사용자의 관심을 얻었는지, 전환율은 그 관심이 실제 행동으로 이어졌는지를 보여준다. 전달 수와 실제 노출 수는 광고가 충분한 기회를 받았는지, 서버가 보낸 광고가 실제 화면 노출까지 이어졌는지를 판단하는 기준이 된다.
이 지표들을 하나의 성과 점수로 집계하면 현재 어떤 광고가 경쟁에서 앞서고 있는지 알 수 있다. 점수가 높은 광고에는 더 많은 노출 기회를 주고, 성과가 낮은 광고는 타기팅이나 소재를 수정한다. 다만 누적 전달 수와 노출 수가 많다는 이유만으로 높은 점수를 주면 오래 운영한 광고가 무조건 유리해진다. 따라서 최근 클릭률과 전환율을 중심으로 비교하고, 전달 수와 노출 수는 표본이 충분해 결과를 신뢰할 수 있는지 판단하는 값으로 사용해야 한다. 새 광고에도 일부 시험 노출을 배정해야 광고 간 경쟁이 고착되지 않는다.
어드민 화면에서는 광고별 전달 수, 실제 노출 수, 클릭률, 전환율, 최종 성과 점수와 순위를 함께 보여준다. 그래야 운영자가 어떤 광고가 좋은 광고인지 확인하고, 좋은 광고의 노출을 확대하거나 낮은 성과의 광고를 개선할 수 있다. 즉, AdServer는 광고를 한 번 고르는 시스템이 아니라 전달 결과를 측정하고 다시 선택 기준을 개선하는 피드백 시스템이어야 한다.
당근의 AdServer 글을 읽고 BuddyStudy의 광고 서버도 이 기준으로 다시 생각해봤다.
2. 누구에게 어떤 광고를 보여줄 것인가
광고를 등록하는 일은 어렵지 않다. 어려운 일은 누구에게 어떤 광고를 보여줄지 결정하는 일이다.
예를 들어 사용자가 BuddyStudy에서 공개 질문을 보고 있다고 하자. 이때 서버는 다음 질문에 답해야 한다.
- 지금 이 화면에 광고를 넣어도 되는가?
- 이 사용자에게 보여줘도 되는 광고인가?
- 아직 예산과 기간이 남아 있는가?
- 이미 너무 많이 보여준 광고는 아닌가?
- 여러 광고 중 어떤 광고가 가장 적절한가?
이 답을 빠르게 만들고, 나중에 왜 그렇게 결정했는지 설명할 수 있어야 한다.
3. 적합한 광고를 고르는 순서
광고 하나를 보여줄 때 서버는 다음 순서로 동작한다.
1. 지금 광고를 넣어도 되는지 확인한다
공개 질문이 너무 적으면 광고를 넣지 않는다. 광고가 질문보다 먼저 보이거나 화면을 방해하면 사용자는 불편해진다.
2. 보여줄 수 없는 광고를 뺀다
다음 조건에 맞지 않는 광고는 후보에서 뺀다.
- 광고를 보여줄 시간이 아니다.
- 광고 예산을 모두 사용했다.
- 이 화면에 맞지 않는 광고다.
- 이 사용자에게 이미 관심 없음으로 표시됐다.
- 같은 사용자에게 너무 자주 보여줬다.
3. 사용자와 광고가 얼마나 맞는지 본다
사용자의 모든 정보를 사용할 필요는 없다. 광고 선택에 필요한 최소한의 정보만 사용한다.
예를 들면 다음과 같다.
- 사용자가 보고 있는 화면
- 사용자가 활동하는 지역
- 광고가 원하는 나이대나 관심사
- 최근에 같은 광고를 본 횟수
목표는 사용자를 자세히 분석하는 것이 아니다. 현재 전달해도 되는 정보인지 판단하는 것이다.
4. 후보 광고의 순서를 정한다
후보가 여러 개면 점수를 계산한다. 점수가 높은 광고를 먼저 보여준다.
다만 항상 1등만 보여주면 새 광고는 기회를 얻지 못한다. 그래서 대부분은 점수가 높은 광고를 고르고, 일부는 다른 후보도 시험한다.
5. 결과를 기록한다
광고를 서버 응답에 넣은 것과 사용자가 실제로 본 것은 다르다. 둘을 따로 기록해야 한다.
광고 후보 선택
-> 응답에 포함: 전달
-> 화면에 충분히 보임: 실제 노출
-> 사용자가 누름: 클릭
-> 사용자가 숨김: 관심 없음
4. 용어를 쉽게 정리하면
| 용어 | 쉬운 뜻 | 왜 필요한가 |
|---|---|---|
| 광고 지면 | 광고가 들어갈 화면의 자리 | 어디에 보여줄지 정한다 |
| 사용자 그룹 | 비슷한 조건을 가진 사용자 묶음 | 누구에게 보여줄지 정한다 |
| 후보 광고 | 지금 보여줄 수 있는 광고 | 불가능한 광고를 먼저 뺀다 |
| 랭킹 | 후보 광고의 순서를 정하는 일 | 가장 적절한 광고를 고른다 |
| 전달(Served) | 서버 응답에 광고를 넣은 것 | 서버가 무엇을 보냈는지 안다 |
| 실제 노출(Impression) | 사용자가 화면에서 광고를 본 것 | 전달과 실제 사용을 구분한다 |
| 클릭률(CTR) | 본 사람 중 누른 사람의 비율 | 광고가 관심을 얻었는지 본다 |
| 전환율(CVR) | 클릭한 사람 중 목표 행동을 한 비율 | 가입이나 구매로 이어졌는지 본다 |
| 광고 비용 대비 수익(ROAS) | 광고비 1원으로 얼마를 벌었는지 | 광고비가 아깝지 않았는지 본다 |
| 1,000회 노출 수익(eCPM) | 광고를 1,000번 보여 얻은 예상 수익 | 광고 후보의 가치를 비교한다 |
예를 들어 광고비로 10만 원을 썼고 광고를 통해 30만 원의 매출이 발생했다면 ROAS는 300%다. 숫자가 높을수록 광고비에 비해 많은 매출을 만든 것이다.
5. 점수는 복잡할 필요가 없다
처음부터 머신러닝을 넣을 필요는 없다. 어떤 이유로 광고가 선택됐는지 설명할 수 있는 규칙부터 시작한다.
광고 점수
= 사용자와 맞는 정도
+ 최근 클릭률과 전환율
+ 표본 신뢰도
+ 시험할 기회
- 오늘 이미 보여준 횟수
- 관심 없음 비율
표본 신뢰도는 전달 수와 실제 노출 수가 판단에 충분한지를 나타낸다. 누적량 자체를 성과로 보지 않고, 적은 표본에서 우연히 나온 높은 클릭률이나 전환율이 과대평가되지 않도록 보정하는 데 사용한다.
새 광고는 기록이 없기 때문에 클릭률과 전환율만으로 판단하지 않는다. 기존 광고와 비슷한 기준으로 시작하고 시험 노출을 배정한 뒤, 실제 반응이 쌓이면 점수를 바꾼다. 어드민은 최종 점수뿐 아니라 점수를 구성한 지표를 함께 확인해야 광고가 선택된 이유를 설명할 수 있다.
6. 가장 중요한 기록 구분
| 기록 | 의미 | 다음 선택에 쓰는 방법 |
|---|---|---|
| 전달 수(Served Count) | 서버가 광고를 응답한 횟수 | 서버가 얼마나 자주 선택했는지 확인 |
| 실제 노출 수(Impressions) | 화면에 실제로 보인 횟수 | 사용자가 실제로 본 수 확인 |
| 클릭 수(Clicks) | 광고를 누른 횟수 | 관심이 있었는지 확인 |
| 노출 뒤 클릭 비율(CTR) | 실제 노출 중 클릭으로 이어진 비율 | 광고가 관심을 얻었는지 확인 |
| 전환 수(Conversions) | 가입, 구매 같은 목표 행동 수 | 광고의 실제 결과 확인 |
| 전환율(CVR) | 클릭 중 목표 행동으로 이어진 비율 | 클릭이 실제 성과로 이어졌는지 확인 |
| 관심 없음 수(Dismissals) | 사용자가 숨긴 횟수 | 불편한 광고를 줄임 |
전달 수만 보면 안 된다. 서버가 광고를 보냈어도 사용자가 화면을 보지 않았을 수 있기 때문이다.
CTR은 클릭 수 / 실제 노출 수이고, CVR은 이 문서의 기준으로 전환 수 / 클릭 수다. 여기서 전환은 가입, 구매, 앱 설치처럼 광고의 목표로 미리 정의한 행동을 뜻한다.
AdMob을 사용하면 어디까지 측정할 수 있나
AdMob은 광고 요청(Requests), 응답에 성공한 요청(Matched Requests), 실제 노출(Impressions), 클릭(Clicks), CTR, 예상 수익(Estimated Earnings), eCPM을 기본 리포트로 제공한다. 따라서 광고가 요청되고 화면에 표시된 뒤 클릭되는 과정은 AdMob만으로도 확인할 수 있다.
반면 관심 없음은 애플리케이션이 제공하는 기능이므로 직접 이벤트를 기록해야 한다. 임의의 가입이나 구매에 대한 CVR도 AdMob이 자동으로 아는 값은 아니다. 앱 설치 전환은 Google Analytics와 연동해 측정할 수 있지만, 그 밖의 전환은 Firebase Analytics나 자체 이벤트로 수집해야 한다. 특히 쿠팡 링크를 연 뒤 쿠팡에서 실제 구매했는지는 쿠팡 측 전환 데이터나 제휴 리포트가 제공되지 않는 한 AdMob만으로 확인할 수 없다.
7. 우리가 먼저 해결할 기술 문제
빠른 선택
광고 후보가 많아져도 짧은 시간 안에 결과를 만들어야 한다. 광고마다 데이터베이스를 따로 조회하면 느려진다. 필요한 통계를 미리 묶어 읽고 한 번에 계산해야 한다.
선택 이유 설명
운영자가 “왜 이 광고가 나왔나요?”라고 물었을 때 답할 수 있어야 한다. 사용자 조건, 광고 상태, 점수에 사용한 값과 최종 결과를 함께 남긴다.
일부 장애 허용
사용자 분석이나 통계 시스템이 잠시 멈춰도 질문 목록은 보여줘야 한다. 광고 선택에 필요한 정보가 없으면 안전한 기본 광고를 사용하거나 광고 없이 응답한다.
과도한 노출 방지
좋은 광고라도 같은 사람에게 반복해서 보여주면 불편하다. 사용자별 노출 횟수와 관심 없음 기록을 확인해 빈도를 제한한다.
8. 현재 구현 방향
BuddyStudy는 지금 복잡한 광고 경매 시스템을 만들려는 것이 아니다.
- 광고를 보여줄 수 있는 상황인지 확인한다.
- 사용자와 조건이 맞지 않는 광고를 뺀다.
- 남은 광고의 순서를 정한다.
- 질문과 광고를 한 목록으로 내려준다.
- 전달, 노출, 클릭, 전환, 관심 없음을 따로 기록한다.
가장 중요한 기준은 광고주에게는 쓸 만한 결과를 주고, 사용자에게는 필요한 정보를 전달하는 것이다. 이 기준을 지키려면 광고를 많이 보내는 기능보다, 누구에게 무엇을 보낼지 선택하는 기능이 먼저 필요하다.