증상: 669통, 클릭 27건, 리드 0건
콜드메일 회신률 문제는 숫자가 아예 안 움직이는 모양이 아니었습니다. 오히려 한 지표는 꾸준히 움직였습니다. 당시 라이브 본문(내부 버전명 v3)으로 나간 메일은 669통이었고, 그중 27통에서 링크 클릭이 나왔습니다. 클릭률로 4.2%입니다. 대시보드만 보면 “반응은 있다”고 읽기 좋은 숫자였습니다.
문제는 그다음 칸이었습니다. 그 27건의 클릭에서 나온 리드, 즉 상담 요청이나 문의는 0건이었습니다. 회신도 없었습니다. 30일 창으로 넓혀 봐도 그림은 같았습니다. 열람 410건, 클릭 128건이 쌓이는 동안 클릭이 매출로 이어진 적은 한 번도 없었습니다.

이런 상황에서 흔히들 문구부터 다시 씁니다. 제목을 바꾸고, 첫 문장을 바꾸고, 버튼 색을 바꿉니다. 저희도 그 방향을 먼저 떠올렸습니다. 하지만 문구를 고치기 전에, 지금 움직이는 그 클릭이 정말 리드로 가는 길 위에 있는지부터 확인해야 했습니다.
처음 의심한 것: 클릭이 늘면 리드도 따라오는가?
첫 가설은 이랬습니다. “클릭이 찍히고 있으니 링크 경로는 살아 있다. 랜딩 페이지가 설득을 못 하고 있을 뿐이고, 클릭을 더 모으면 언젠가 문의가 나온다.” 이 가설 위에서는 링크를 지켜야 맞습니다. 메일 안에서 유일하게 움직이는 숫자가 링크 클릭이었기 때문입니다.
이 가설에는 함정이 하나 있었습니다. 클릭률은 무료로 쌓이는 지표입니다. 받는 사람이 링크를 한 번 누르는 데에는 아무 비용이 들지 않고, 그 클릭이 구매 의사를 뜻한다는 보장도 없습니다. 클릭을 지키는 선택이 맞으려면, 클릭한 사람 중 일부라도 다음 단계로 넘어간 기록이 있어야 했습니다.
그래서 질문을 바꿨습니다. “클릭을 어떻게 늘리나”가 아니라 “클릭한 사람이 그다음에 무엇을 했나”. 이 질문에 답하려면 메일 발송 도구의 숫자가 아니라, 실제로 들어온 리드 쪽 기록을 열어야 했습니다.
무엇으로 확인했나?
확인에 쓴 수단은 세 가지였습니다. 추측 대신 기록 원본을 직접 열어 보는 방식으로 골랐습니다.
- 리드 목록 파일에서 유입 경로가 “메일 직접”인 항목 4건을 한 줄씩 열어, 그중 콜드메일 회신이 있는지 확인
- 8월 13일에 따로 뽑아 둔 퍼널 기록: 클릭에서 진단 시작, 진단 시작에서 문의까지 단계별 인원
- 발송 기록의 30일 창 집계: 열람 410건, 클릭 128건
첫 번째 수단이 가장 결정적이었습니다. “메일로 들어온 리드가 4건 있다”는 숫자만 보면 콜드메일이 무언가를 만들어 낸 듯 보입니다. 하지만 4건을 열어 보니 콜드메일 회신은 하나도 없었습니다. 콜드메일과 무관한 경로의 문의 1건, 상대 쪽에서 먼저 연락해 온 파트너십 제안 1건, 그리고 대표 메일 주소로 들어와 자동 등록된 항목뿐이었습니다.
두 번째 수단은 이 현상이 일회성이 아닌지 보려고 썼습니다. 8월 13일 퍼널은 클릭 24건, 진단 시작 7건, 문의 0건이었습니다. 클릭한 사람 일부는 실제로 랜딩까지 들어와 진단을 시작했지만, 거기서 멈췄습니다. 2주 넘게 떨어진 두 시점이 같은 모양이라는 점이 중요했습니다.

알리바이: 왜 링크 경로는 범인이 아니었나
여기서 첫 가설은 무너졌습니다. 클릭이 늘면 리드도 따라온다면, 669통·27클릭 구간이나 8월 13일 구간 어디에서든 문의가 한 건은 나왔어야 합니다. 두 구간 모두 0이었고, 리드 목록에도 콜드메일 회신은 없었습니다. 링크 경로는 “살아 있지만 아무 데도 가지 않는 길”이었습니다.
그렇다고 랜딩 페이지를 범인으로 지목할 수도 없었습니다. 랜딩을 고치면 결국 같은 링크 경로에 돈과 시간을 더 쓰게 되고, 그 경로가 리드를 만든 실측은 0건입니다. 반대로 메일 안에서 한 번도 제대로 시험하지 않은 경로가 하나 있었습니다. 받는 사람이 그냥 답장을 쓰는 경로입니다.
링크 축을 지키는 선택은 0원짜리 지표를 지키느라 유일하게 안 해 본 것을 안 해 보는 것이다.
한 가지 가능성은 남겨 뒀습니다. 본문이 아니라 받는 사람 목록 자체가 문제일 수도 있습니다. 애초에 이 업무를 하지 않는 회사에 보냈다면 어떤 본문을 써도 회신은 없습니다. 이 가능성은 지우지 않고, 뒤에서 설명할 판정 기준의 “기각” 칸에 그대로 넣었습니다.
진짜 원인으로 지목한 것: 한 통에 요청이 세 개
본문을 다시 읽자 구조적인 문제가 보였습니다. 한 통이 받는 사람에게 세 가지 행동을 동시에 요구하고 있었습니다. 저희가 추정한 사실이 틀렸으면 “아니오” 한 줄로 정정해 달라는 요청, 링크를 눌러 “지금 확인해 보기”를 해 달라는 요청, 그리고 한 줄만 회신해 달라는 요청입니다.
- 정정: “틀렸다면 '아니오' 한 줄만 주셔도 됩니다”
- 링크 클릭: “지금 확인해 보기”
- 회신: “한 줄만 회신 주시면”
요청이 여러 개면 받는 사람은 무엇부터 할지 고르느라 멈춥니다. 선택 마비라고 부르는 현상이고, 마비의 기본 결과는 행동이 아니라 삭제나 보류입니다. 그나마 고르는 사람은 가장 부담 없는 행동, 즉 링크 클릭을 고릅니다. 클릭 4.2%와 회신 0이라는 저희 숫자가 정확히 이 모양이었습니다.
다만 이 시점에서 원인은 확정이 아니라 지목 단계였습니다. 요청 수가 회신을 막는다는 주장은 가설이고, 이 가설을 시험하려고 아래 실험을 설계했습니다. 실험의 결과는 이 글을 쓴 기록에 담겨 있지 않습니다.
고친 방법: 요청 두 개만 빼고 나머지는 글자 그대로
수리는 일부러 작게 했습니다. 새 본문은 당시 라이브 본문에서 요청 두 개만 뺐습니다. 실제 차이는 4줄 삭제, 2줄 추가입니다. 금액을 계산해 보여 주는 문단과 “절감 보장 아님” 같은 표시광고법 대비 문구는 한 글자도 바꾸지 않았습니다. 바꾼 축이 요청 수 하나여야 결과를 그 하나에 돌릴 수 있기 때문입니다.

적용 범위도 좁혔습니다. 실험군 B, 즉 수신자 해시가 짝수이고 직원 수를 인용할 수 있는 회사에만 새 본문을 보냈고, 다른 실험군 두 개는 그대로 뒀습니다. 켜는 방법은 환경변수 하나입니다. 매일 08:50에 본문을 만드는 crontab 줄 앞에 COLDMAIL_REPLY_ONLY_LIVE=1 을 붙였습니다. 처음 만든 변경(PR #423)은 파생 기준이 틀려 PR #425로 바로잡았습니다.
이렇게 하면 랜딩으로 가는 다리가 실험군 B에서 사라집니다. 지금 유일하게 움직이던 지표(30일 창 클릭 128 / 열람 410)를 저희 손으로 끄는 셈입니다. 그 대가는 클릭이 매출로 이어진 적이 0건이라는 실측으로 치렀습니다.
왜 전부 바꾸지 않았나?
더 과감한 선택지도 있었습니다. 세 가지를 검토했고 모두 버렸습니다.
| 대안 | 버린 이유 |
|---|---|
| 모든 실험군의 본문을 한꺼번에 교체 | 비교할 대조군이 사라져, 회신율이 바뀌어도 그 원인을 본문에 돌릴 수 없다 |
| 링크는 두고 정정 요청만 제거 | 요청이 2개로 남아 “요청이 여러 개면 마비” 가설 자체를 시험하지 못한다 |
| 8월 27일 발송분의 회신이 다 올 때까지 대기 | v3의 리드 0은 669통으로 이미 확정된 값이라 기다려 얻는 정보가 없고, 그동안 0원짜리 클릭만 계속 쌓인다 |
세 번째 대안에는 사연이 있습니다. 8월 27일에 v3 라벨로 경리 담당자 대상 메일 379통이 나갔고, 그 회신이 아직 들어오는 중이었습니다. 깔끔하게 하려면 그 창이 닫힐 때까지 기다리는 게 맞아 보였습니다. 하지만 비교의 기준이 되는 “v3의 리드 0”은 이미 669통으로 확정돼 있었습니다. 기다림이 그 숫자를 바꿀 가능성은 없었습니다.
고치는 중에 드러난 두 번째 문제: 플래그는 켰는데 옛 본문이 나간다
수리를 켠 뒤, 설정값만 믿지 않고 크론과 같은 방식으로 직접 실행해 봤습니다. 여기서 예상하지 못한 문제가 나왔습니다. 새 본문은 630자여야 하는데, 실행 결과는 496자짜리 구버전 본문이었습니다.
원인은 코드가 아니라 위치였습니다. 로컬 체크아웃이 원격 저장소보다 1커밋 뒤처져 있었습니다. 크론은 cd /mnt/c/Users/kimky/b2b-consulting 로 바로 그 체크아웃에 들어가 실행합니다. 원격에 정정본을 올려도 크론이 그 코드를 볼 수 없었고, pull 없이 다음 날 아침을 맞았다면 정정 전 문구가 실제로 나갈 뻔했습니다.

git pull --ff-only 로 당겨 해소했습니다. 이 일에서 남긴 교훈은 한 문장입니다. “플래그를 켰다”와 “그 코드가 크론이 실제로 도는 경로에 있다”는 서로 다른 사실입니다. 앞쪽은 설정 파일만 봐도 알지만, 뒤쪽은 실행해 봐야 압니다. 크론이 0회 돌았는데 아무도 몰랐던 사례는 크론 실행 0회 감사 글에 따로 정리했습니다.
같은 실수를 막는 장치
이번에 둔 장치는 세 가지입니다. 결과 해석을 미리 못 박기, 켠 사실을 실행으로 확인하기, 되돌리는 길을 한 줄로 남기기입니다.
첫째, 판정 기준을 실험 전에 고정했습니다. 이 저장소에서는 “2주 뒤에 보니 애매하다”로 끝나는 실험이 반복됐습니다. 그래서 무엇이 나오면 채택이고 무엇이 나오면 기각인지를 켜는 날 적어 뒀고, 판정일은 2026년 9월 11일로 정했습니다.
| 축 | 값 |
|---|---|
| 표본 | 실험군 B 평상 25~35통/일 × 주 5일 → 2주 약 300통 |
| 채택 | 회신 3건 이상(1%) → 모든 v3 실험군으로 확대 검토 |
| 기각 | 회신 0~1건 → 플래그 제거, 링크 경로 복귀, 받는 사람 목록 쪽으로 이동 |
| 즉시 중단 | 반송률이 v3 대비 +2%p 초과 |

즉시 중단 조건을 둔 이유도 적어 둘 만합니다. 본문이 630자로 짧아지면 스팸 필터가 다르게 반응할 수 있고, 그건 보내 보기 전에는 모릅니다. 회신을 늘리려다 도달 자체를 잃으면 실험이 의미를 잃습니다.
둘째, 켠 직후 세 가지를 실행으로 확인했습니다. 크론과 같은 환경변수로 본문 생성 함수를 불러 결과가 회신 전용 본문인지, 요청이 “회신” 하나인지, 링크 버튼이 없는지, 금액 문단이 남았는지, 길이가 630자인지 봤습니다. 이어 크론과 같은 명령을 실제로 돌려 큐 391행 중 회신 전용 본문이 178행이고 링크·HTML 버튼이 0개임을 확인했습니다. 마지막으로 플래그를 빼면 v3 본문으로 돌아오는지도 확인했습니다.
셋째, 저장 라벨과 되돌리는 길을 분리해 뒀습니다. 발송 기록에 v3와 회신 전용 본문이 서로 다른 라벨로 남기 때문에 전후 비교가 가능합니다. 되돌리기는 crontab 그 한 줄에서 환경변수만 지우면 끝나고, 바꾸기 전 crontab은 292줄짜리 백업 파일로 남겼습니다.
이 기록이 아직 모르는 것은 무엇인가?
정직하게 남겨 둘 부분이 있습니다. 이 글의 근거가 된 기록은 실험을 켠 날의 기록입니다. 2026년 9월 11일 판정에서 회신이 몇 건 나왔는지, 요청 수를 줄인 가설이 채택됐는지 기각됐는지는 이 기록에 없습니다. 반송률이 실제로 어떻게 움직였는지도 마찬가지입니다.
그래도 이 과정에서 확정된 사실은 있습니다. 클릭 27건과 리드 0건은 669통으로 이미 정해진 값이고, “클릭이 늘면 리드도 온다”는 가설은 두 시점에서 모두 반증됐습니다. 그리고 설정을 켜기만 하면 운영이 바뀐다고 믿었다면, 정정 전 496자 본문이 그대로 나갈 뻔했습니다.
메일 클릭이 실제 방문으로 이어졌는지를 GA4로 따로 대조한 이야기는 메일 클릭률과 GA4 방문의 차이에 있습니다. 비슷하게 숫자는 움직이는데 문의가 없는 영업 메일이나 자동화 문제를 겪고 있다면 상담으로 상황을 알려 주셔도 좋습니다.