
노션에 정리해놓았다가 드디어 블로그로 옮기는 작업을 하고 있다.
이번에 쓰는 글을 우리 서비스의 핵심기능인 이메일 서버관련 글이다.
먼저 우리 서비스가 모르시는 분이 있을 수도 있는데 이 서비스를 만든 가장 큰 이유 중 하나
즉 페인포인트는 여러 메일이 섞인다는 것이다.
먼저 예시를 보자

위 이미지는 제 받은메일함입니다.
메일 종류를 보면 결제 내역, 뉴스레터, facebook, github 등등 뒤죽박죽 섞여있습니다.
이를 정리하기 위해 메일함을 만들어서 분류하기도 귀찮습니다.
그렇다고 뉴스레터 전용 이메일을 만든다? 뉴스레터 이메일 갔다가 다시 원래 이메일 갔다가 하기가 번거롭다.
여기

현재 서비스를 보면 이렇게 이메일이 도착하면 오늘의 뉴스레터 페이지에서 볼 수 있다.
이 화면을 보여주면 크루들은 이렇게 말한다
"이거 어디서 긁어오는거야?"
"크롤링 해도 괜찮아??"
그럼 이렇게 대답한다.
"이거 이메일 서버를 통해서 직접 이메일 받을 거야!!"
그렇다면 이제부터 이메일서버가 왜 필요했는지? 어떻게 구축했는지에 대해서 알아보자 ㅎㅎ

뉴스레터는 크롤링 같은걸 해오는게 아니다 이것도 하나의 저작권으로 인정되기 때문에 우리가 함부로 가져올 수가 없다.

우리 서비스는 그대로 보여주기 때문에 공정사용에 해당하지 않는다.
따라서 누구나와서 볼 수 있게 하면 불법이 된다.
오직 뉴스레터를 신청한 당사자만 메일을 통해서 볼 수 있다.
그렇기에 우리서비스는 로그인이 필수이고 이메일을 받을 수 있어야 했다.
기존의 이메일은 이렇게 더럽다.
이게 너무 불편했다. 또 가끔은 이렇게 스팸메일함에 들어가있다.

지메일 같은 경우는 아래의 설정을 해줘 스팸으로 오지 않는다

그래서 뉴스레터만 받을 수 있는 앱이 있으면 어떨까 생각이 들었다.
이렇게 하려면 이메일을 받아야했다.
첫 번째 시도: Gmail API로 뉴스레터 긁어오기
이전에 했던 작은 사이드 프로젝트에서는 인프라 구축에 익숙하지 않았고 여러가지 방법도 잘 찾아보지 않았다.
그 당시 조사했던 방법은 딱 두 가지였다. Gmail API를 통해 활용하는 것 이메일 서버를 구축하는 것
이 당시 인프라 구축에 익숙하지 않았고 비용을 최대한 아끼기 위해 돈의 거의 들지 않는 Gmail API로 부턱대고 시작했다.
Google Gmail API를 이용해서 다음과 같은 구조로 만들었다.
1. 유저가 OAuth로 우리 서비스에 Gmail 접근 권한을 준다.
2. 우리가 유저의 Gmail에 들어가서 뉴스레터 메일만 골라 읽고
4. 그 내용을 파싱해서 DB에 저장한다.
처음에는 꽤 그럴듯해 보였다.
사용자는 기존 이메일 주소를 그대로 쓰면 되고 우리는 권한만 받아서 필요한 뉴스레터만 읽으면 되니 별도 메일 서버를 운영하지 않다도 됐다.
실제로도 잘 동작했다.
하지만 엄청난 문제가 있었다.
신규회원가입을 하려면 화면이 아래와 같이 뜬다.

원인은 바로 CASA다
Gmail 본문을 읽으려면 넘어야 하는 벽, CASA
구글은 요즘, Gmail 같은 민감한 사용자 데이터에 접근하는 앱에 대해
보안 검증을 굉장히 강하게 요구하고 있다.
그 중심에 있는 제도가 바로 CASA (Cloud Application Security Assessment)다.
요약하면 이런 제도다.
“너희 앱이 사용자 데이터를 안전하게 다루는지,
제3의 보안 기관이 공식적으로 확인해주는 인증 제도”
특히 Gmail 본문을 읽는 권한 같은 걸 쓰려면,
그냥 “우리가 잘 할게요” 수준으로는 안 되고,
Tier 2 이상의 CASA 인증을 요구한다.
CASA Tier 간단 정리
- Tier 1 – 개발자가 체크리스트를 보고 셀프 점검하는 단계 (무료)
- Tier 2 – 공인 보안 실험실에서 코드/구성 자동 분석 + 검증
- Tier 3 – 인프라, 네트워크, 데이터 저장 방식까지 포함한 풀 보안 감사
문제는 비용이다.
- Tier 1: 무료
- Tier 2: 수백만원
- Tier 3: 수천만원
즉, 작은 팀이나 사이드 프로젝트 입장에서
“Gmail API로 메일 본문을 읽는 서비스”를 만들려면
CASA Tier 2 비용 때문에 사실상 불가능에 가깝다
라는 결론이 나온다.
그 당시에는 자체 CASA Tier 2를 받을 수 있었다.
레퍼런스도 너무 부족해서 어디서부터 시작해야할지 감잡기도 어려웠고 링크드인에 어떤 현업자분이 인증받았다해서 연락을 드렸지만 회신이없었고 우리나름대로 여러가지 시도를 해보았지만 실패했었다.
심지어 지금은 자체 스캔 프로세스는 지원하지않고 무조건 인증기관에 돈을 주고 받게 되어잇다.

우리도 결국 이 문제 때문에, 정식 출시를 하지 못햇다.
프로젝트 기간도 거의 끝나갔고 아쉬움에 남았었다.
(혹시 지금 CASA Tier 2 인증을 받고 싶다면 여기를 참고하면 좋을 것 같다)
같은 실수를 반복하지 않기 위해: 이메일 수신 옵션들 비교
그렇게 우테코 팀프로젝트를 시작하고 뾰족한 대안이 없을 때 뉴스레터 관련 아이템을 제시했고 이전에 수많은 자료조사와 실패한 경을 토대로 팀원들을 설득했고 결국 이 프로젝트를 진행하게되었다.
이 아이템의 핵심은 이메일 도착이다.
찾아본 방법은 크게 네 가지 정도다.
1. AWS SES로 메일로 수신
2. SendGrid / Mailgun inbound API
3. Cloudflare Email Routing
4. 수신 전용 이메일 서버 직접 구축
1) AWS SES(Simple Email Service)로 이메일 받기
가장 먼저 검토한 선택지는 AWS SES로 메일을 받는 방식이다.
news@mydomain.com 같은 주소로 온 메일을 SES가 대신 수신하고, 그 메일을 S3에 저장하거나 Lambda를 실행하거나 SNS로 이벤트를 발행하는 식으로 다른 AWS 리소스로 넘겨주는 구조다.
이미 AWS를 쓰고 있다면, 그림 자체는 꽤 깔끔하다.
- 직접 메일 서버를 운영할 필요가 없다
- Postfix, Dovecot 같은 걸 설치하고 운영/백업/보안 패치를 신경 쓸 필요가 없다.
- AWS가 기본적인 스팸 필터링을 어느 정도 해준다
- 우리가 여러 이메일 관련 설정과 스팸 필터를 처음부터 다 짜는 것보다 부담이 적다.
- Lambda와 바로 붙일 수 있다
- “메일 수신 → Lambda 트리거 → 본문 파싱 후 DB 저장” 같은 파이프라인을 서버 없이 구성할 수 있어서,
- 초기에 빠르게 프로토타입을 만들기에는 꽤 매력적인 옵션이다.
초기 작은 서비스이거나,
“메일 수신량이 많지 않고, AWS 안에서만 빠르게 파이프라인을 구성하고 싶다”면
실제로 도입을 충분히 고려해볼 만한 구조다.
하지만 우리 서비스 기준으로는, 치명적인 단점이 몇 가지 있었다.
첫 번째는 경제성 문제다.
SES는 발송뿐만 아니라 수신도 건당 과금이 붙는다.

보수적으로 계산을 해보았다.
평균 1명당 4개의 뉴스레터를 구독하고 그 뉴스레터는 매일 도착한다고 해보자
그럼 회원수가 500명일 때 하루에 2000개의 메일을 수신해야한다.
여기에 청크 비용도 계산을 해야한다.
도착하는 이메일은 뉴스레터고 거의 대부분이 HTML이다
HTML 평균 크기는 11.5KB로 계산했다. (8,000 ~ 15,000자 -> 평균 11,500자)
메일 크기 11.5KB 기준 청크 비용 계산
✔ 청크 단위 = 256KB
→ 11.5KB / 256KB = 0.04492 청크
✔ 청크 비용
0.04492 × 0.00009 USD = 0.000004042 USD / 건
✔ 메시지 비용
0.0001 USD / 건
최종 1건당 비용 : 0.0001 + 0.000004042 = 0.000104042 USD / 건
최종 비용 예상
| 회원 수 | 하루 수신량 | 하루 비용(USD) | 월 비용(USD) |
| 500명 | 2,000건 | 0.208 USD | 6.24 USD |
| 1,000명 | 4,000건 | 0.416 USD | 12.48 USD |
| 2,500명 | 10,000건 | 1.040 USD | 31.20 USD |
| 5,000명 | 20,000건 | 2.080 USD | 62.40 USD |
회원 수가 증가할 수록 비용이 선형 증가하게된다.
중요한건 여기에 스팸처리 비용은 계산하지 않았다.
스팸 메일도 똑같이 비용이 든다.
뉴스레터 서비스 특성상,
- 사용자 수가 늘어나고
- 구독하는 뉴스레터 종류가 많아질수록
- 하루에 들어오는 메일 수도 기하급수적으로 증가한다.
초기에야 “얼마 안 나오네?” 싶다가도,
규모가 커졌을 때 고정 비용이 아닌 ‘트래픽 기반 비용’으로 계속 빠져나간다는 점이 큰 부담이었다.
두 번째는 커스터마이징의 제약이다.
SES를 쓰는 순간, 메일 수신 이후의 파이프라인이 AWS 리소스 중심으로 고정되는 느낌이 있다.
- Maildir 같은 전통적인 디렉터리 구조를 그대로 쓰기도 어렵고
- 원본 .eml 파일을 어떻게 보관할지, 장기 보관 정책을 어떻게 가져갈지 등에서
SES 설계에 맞춰서 생각해야 한다. - 인프라를 완전히 AWS 밖으로 빼거나,
자체 메일 서버로 구조를 전환하고 싶어지는 시점이 왔을 때 마이그레이션 비용도 고려해야 한다.
우리 서비스처럼
- 장기적으로 메일을 아주 많이 받게 될 가능성이 높고
- 원본 메일을 그대로 쌓아두고,
- 파이프라인과 저장 구조를 우리가 원하는 대로 세밀하게 설계하고 싶다
라는 요구사항을 생각했을 때,
초기에는 편하지만, 규모가 커질수록 비용과 제약이 서서히 발목을 잡을 수 있는 선택지 라는 결론을 내렸다.
그래서 실제 도입 후보에서 완전히 제외한 것은 아니지만,
프로토타입/소규모 서비스에는 좋지만,
장기적으로 우리가 가고 싶은 아키텍처와는 방향이 다르다고 판단했다.
2) SendGrid/Mailgun 수신 API
한 마디로 하면 “메일을 직접 ‘받아’ API로 전달해주는 서비스”
SES 다음으로 눈이 간 건 “메일 수신을 SaaS에 맡기고, 우리는 HTTP로만 받자”는 접근이었다.
메일 프로토콜(MX/SMTP) 세계를 직접 다루지 않아도 되고, 우리 서버는 웹훅 요청 하나만 처리하면 되니까 초반 생산성이 압도적으로 좋아 보였다.
동작 방식
- 발신자 → (MX) → SendGrid/Mailgun 수신 → 메일 파싱 → 우리 Webhook 엔드포인트로 POST → 저장/파이프라인 실행
- SendGrid는 Inbound Email Parse Webhook 형태로 제공한다.
또 하나 마음에 들었던 포인트는, Webhook이 실패해도 재시도 메커니즘이 있다는 점이었다. 예를 들어 SendGrid는 우리 엔드포인트가 5xx로 응답하면 큐잉 후 재시도하고, 2xx를 받으면 처리를 끝낸다(최대 3일 재시도 후 드랍)
우리 기준에서 걸렸던 지점들
1) 비용이 고정 + 제한 형태로 다가온다
SES가 “쓴 만큼”에 가깝다면, 이쪽은 월 플랜(포함량 + 초과 과금) 성격이 강했다.
우리 서비스 가정(1인당 4개/일, 30일 기준)으로 수신량만 단순 환산하면 대략 아래 정도다.
| 회원 수 | 월 수신량(건) | Mailgun 추정 월 비용(USD) | SendGrid 추정 월 비용(USD) |
| 500 | 60,000 | 약 48 (Foundation 50k + 초과 10k) | 약 33.25 (Essentials 50k + 초과 10k) |
| 1,000 | 120,000 | 약 112 (Scale 100k + 초과 20k) | 약 52.95 (Essentials 100k + 초과 20k) |
| 2,500 | 300,000 | 약 310 (Scale 100k + 초과 200k) | 약 214.95 (Essentials 100k + 초과 200k) |
| 5,000 | 600,000 | 약 640 (Scale 100k + 초과 500k) | 약 484.95 (Essentials 100k + 초과 500k) |
Mailgun은 무료 구간이 작고(하루에 100통), 유료는 월 구독(Basic이 월 15$)이 붙고, SendGrid도 월 구독(월 19.95$)이 시작점이라 장기적으로 수신량이 늘어나는 서비스에선 부담이 될 수 있다.
핵심은 수신량 증가가 곧 비용 증가로 직결되고, 스팸/오발송처럼 “원치 않는 메일”도 같은 방식으로 비용에 들어온다는 점이었다.
2) 원문(.eml) 보관이 ‘공짜’가 아니다
Maildir처럼 “메일이 오면 원문이 파일로 남는” 흐름이 아니라, Webhook으로 받은 결과를 기반으로
원문(raw MIME)을 그대로 저장할지 어디에,
얼마나 오래 보관할지(S3/DB/파일)
장애/버그 시 재처리(리플레이) 를 어떻게 할지 를 별도로 설계해야 한다.
즉 “수신”은 SaaS가 해주지만, “아카이빙”은 결국 우리가 책임져야 했다.
초기 구현 속도는 최고였다. 하지만 우리 서비스는 이메일 수신이 핵심 도메인이고, 1~2달 하고 끝낼 프로젝트도 아니다. 그래서 월 플랜 기반 비용 구조 + 원문 보관 설계 부담까지 합쳐 보면, 장기적으로 우리가 원하는 아키텍처 방향과는 거리가 있다고 판단했다.
3) 직접 이메일 서버 운영하기
마지막 선택지는, 우리가 직접 이메일 수신 전용 서버를 운영하는 방식이었다.
즉, SendGrid/Mailgun 같은 외부 Inbound 서비스에 의존하지 않고 SMTP(Postfix)로 직접 수신하고, Maildir에 원문을 저장한 뒤 내부 파이프라인(파서/저장/후처리)로 넘기는 구조다.
결론부터 말하면 우리는 이 방식을 선택했다.
왜 직접 운영을 택했을까?
1) 비용이 “고정비”로 떨어진다
Inbound SaaS는 보통 월 구독(플랜) 형태가 시작점이다. 예를 들어 SendGrid는 Essentials가 월 $19.95~부터 시작하고, Mailgun도 무료 구간 이후는 유료 플랜을 전제로 한다.
반면 직접 수신 서버는 ‘메일 건수’가 아니라 ‘서버/디스크’ 중심으로 비용이 잡힌다.
서울 리전 기준으로 아주 러프하게 잡으면(온디맨드)
- EC2 t4g.micro: 시간당 약 $0.0104 → 월 약 $7.59
- EBS gp3 10GB: 대략 $0.08/GB-month 기준이면 월 $0.80
합치면 월 $8~9 수준에서 시작할 수 있고, 무엇보다 메일이 늘어도 “건당 과금”이 붙지 않아서 규모가 커질수록 예측이 쉬워진다.
여기에 Saving plans을 적용하면 40%는 더 싸진다.
또한 데이터 전송은 인바운드는 과금이 없고(원칙), 아웃바운드는 월 100GB까지 무료 구간이 있다.
뉴스레터 수신/파싱 구조에서는 보통 인바운드가 중심이라 네트워크 비용이 폭발하는 패턴이 상대적으로 덜했다.
2) 설계를 마음대로 가져갈 수 있다
이 방식의 핵심은 “제약이 없다”였다.
- Maildir 구조 그대로 저장(원문이 파일로 쌓임)
- 파싱 로직/재처리 전략(실패 메일 재시도, 파서 교체 등)
- 첨부파일 처리, 전처리/후처리
- 보관/삭제 정책(예: N일 보관, 특정 발행처 영구 보관)
- 트래킹/감사 로그(수신 시각, 처리 시각, 원문 해시 등)
메일이 핵심 도메인인 서비스에서, 이 “완전한 통제권”은 장기적으로 큰 자산이 된다.
3) 원본 이메일(.eml)을 그대로 확보할 수 있다
Inbound API는 “파싱된 결과”를 주는 대신, 원문을 장기 보관하려면 결국 별도 저장 설계가 필요하다.
반면 자체 수신은 원문(.eml) 확보가 기본값이라, 나중에 파서가 바뀌어도 “원문 기준으로 재처리”가 가능하고, 문제 상황에서 디버깅도 훨씬 단단해진다.
4) 대량 수신/버스트에 강하다
Postfix는 원래 큐 기반으로 트래픽을 흡수하도록 설계되어 있다.
뉴스레터처럼 특정 시간대에 몰아치는 패턴에서도, 큐/워커/파서 처리량을 조절하면서 안정적으로 버틸 수 있다는 점이 매력적이었다.
물론, 공짜는 아니다
직접 운영을 선택하는 순간 아래는 “우리 책임”이 된다.
- 스팸/어뷰징 대응(차단, 레이트리밋, 로그 감시)
- 보안 패치/권한 관리/접근 통제
- 디스크/백업/모니터링(메일이 쌓이는 속도, 큐 적체, 파서 지연)
다만 우리는 이메일이 서비스의 중심이고, 1~2달짜리 실험이 아니라 지속 운영이 전제라서, 이 운영 부담을 감수하더라도 비용 예측 가능성 + 설계 자유도 + 원문 확보 쪽이 장기적으로 더 맞다고 판단했다.
'서비스 운영 일지 > 봄봄' 카테고리의 다른 글
| 봄봄 AWS 비용 다이어트 이야기 (3) | 2025.12.09 |
|---|---|
| 봄봄에서 서드파티 라이브러리를 대하는 방법 (2) | 2025.11.22 |
| 봄봄 서비스에 맞게 검색 성능 개선기 (4) | 2025.11.17 |
| 저장이 왜 안되는 거지? (0) | 2025.11.15 |