이 글의 위치: 기술 블로그 → AI · 음성 시스템. 작성·검증 방식은 Editorial Policy 참조. 본 글의 수치는 모두 본인이 운영하며 직접 측정한 1 차 데이터입니다.
운영 컨텍스트
1:1 AI 음성 상담 서비스를 9 개월간 운영하며, WebRTC 의 TURN relay 를 두 가지 모드로 거쳐왔다.
- 2025-08 ~ 2025-10 (3 개월) — 외부 TURN 서비스(이하 "외부 X") 구독
- 2025-11 ~ 현재 (6 개월) — coturn 1.5.x self-host (GCE n2-standard-2 단일 노드)
같은 기간 누적 통화 약 4,200 건, 평균 통화 길이 6 분 12 초, peak 동시 통화 14 건. 작은 규모지만 두 모드를 모두 동일 트래픽으로 돌려보았기 때문에 비교 의미가 있다.
배경 개념(STUN vs TURN, NAT 종류별 성공률 분포) 은 이전 글 WebRTC STUN과 TURN, 언제 무엇을 — NAT 종류 × 성공률 매트릭스 와 WebRTC 연결의 6단계 — Offer/Answer부터 ICE Connected까지 참조.
외부 TURN 서비스 3 개월
선택한 이유는 단순했다: 운영 부담 0, 30 일 무료, 한국 GSLB 노드 보유. 결과를 측정하니 가격·운영 부담은 적었지만 latency 가 우리 사용 패턴에는 부담이 됐다.
측정값
| 지표 | 외부 X (서울 노드) | 비고 |
|---|---|---|
| ICE connectivity check 평균 RTT | 38 ms | TURN relay 경유 |
| ICE connectivity check p95 | 89 ms | |
| TURN 할당 (allocate) latency p50 | 142 ms | offer→answer 직후 1 회 |
| 월 비용 (peak 14 동시) | $46 | 동시 14 기준 플랜 |
| 장애 (서비스 측 통보) | 1 회 / 3 개월 | 약 7 분 부분 장애 |
ICE connect 자체는 빠르지만, TURN allocate 의 100ms+ 가 통화 시작 체감에 직접 영향. 1:1 AI 상담은 첫 음성이 나오기까지의 인지 latency 가 사용자 평가에 매우 민감하다.
발견한 제약
3 개월 운영하며 두 가지 우리 사용 패턴 특성이 외부 서비스와 잘 맞지 않는다는 결론이 나왔다.
- 세션이 짧고 자주 만들어진다 — 평균 6 분, 일일 수십 건. allocate 비용이 통화당 한 번씩 반복.
- 트래픽 대비 비용이 선형이 아니다 — 작은 동시 호 14 명에 $46. 1 GB 단가는 합리적이지만 우리는 동시 호 수에 묶인 플랜이라 GB-당 단가의 이점을 못 받는다.
이 두 가지가 합쳐져 "이 정도면 self-host 가 더 나을 수 있다" 는 가설을 시작점으로 잡았다. 의사결정 4 축의 자세한 정리는 WebRTC 외부 TURN 서비스 vs self-host — 4축 의사결정 에 별도로 적었다.
Self-host coturn 6 개월
구성
- GCE n2-standard-2 (vCPU 2, 메모리 8 GB), Seoul region, $48/월
- coturn 4.6.x, Ubuntu 22.04, systemd unit
- 도메인 + Let’s Encrypt 인증서 (TLS over 5349)
- realm·user·credential 은 우리 서비스 백엔드에서 동적 TURN credential 발급 (TTL 1 시간)
- iptables 룰로 UDP 49152-65535 전체 개방
측정값 (동일 트래픽 기준)
| 지표 | self-host (Seoul) | 외부 X 대비 |
|---|---|---|
| ICE connectivity check 평균 RTT | 21 ms | −45 % |
| ICE connectivity check p95 | 52 ms | −42 % |
| TURN allocate latency p50 | 38 ms | −73 % |
| 월 비용 (peak 14 동시) | $48 | +4 % |
| 장애 (내부 발생) | 2 회 / 6 개월 | 모두 자체 운영 부주의 |
비용은 거의 같지만 latency 가 모든 백분위수에서 의미 있게 짧다. 핵심 차이는 single hop — 우리 백엔드 노드와 같은 region (Seoul) 이라 미세하지만 일관된 절감이 나온다.
운영 중 만난 실패 모드
운영 6 개월 동안 두 번의 장애가 있었고, 둘 다 self-host 라 발생한 종류였다.
- 2025-12-XX, 인증서 갱신 실패 — Let’s Encrypt 갱신 cron 이 systemd restart 와 충돌. coturn 이 옛 인증서로 재시작되면서 TLS 핸드셰이크 실패 17 분. 이후 cron 에 systemd reload 만 호출하도록 변경.
- 2026-02-XX, conntrack 테이블 만석 — 동시 호 폭주 시 conntrack 한계가 먼저 깨졌다.
net.netfilter.nf_conntrack_max를 8 배로 올린 뒤 재현 안 됨.
추가로 만나지는 않았지만 운영 중 "끊긴다" 류 호소가 들어왔을 때 어떤 순서로 보았는지는 WebRTC 디버깅 ‘끊긴다’ 현상이 보일 때 보는 5가지 에 정리했다. self-host 든 외부 서비스든 디버깅 순서는 동일하다.
9 개월 비교 한 줄
같은 비용으로 latency 모든 백분위수에서 self-host 가 의미 있게 빠르다. 단, 인증서·conntrack 같은 운영 부담을 본인이 진다.
3 개월 외부 서비스 → 6 개월 self-host 의 전환은 결과만 보면 잘한 결정이지만, 모든 팀에게 권하는 답은 아니다. 우리 케이스에 self-host 가 맞은 이유는 다음 네 가지가 모두 충족됐기 때문이다:
- 트래픽이 동시 호 ≤ 50 수준 — n2-standard-2 한 대로 충분
- 백엔드와 같은 region 에 둘 수 있음 — single hop 효과
- Linux 시스템 (conntrack, iptables, systemd, cron) 운영 경험이 1 인 보유
- 통화 시작 latency 가 사용자 평가에 직접 영향 — 비용·운영부담을 감수할 가치가 있음
위 네 조건 중 하나라도 빠지면 외부 서비스가 합리적이다. 특히 ② (region 일치) 가 빠지면 self-host 의 핵심 이점이 사라진다.
다시 선택한다면 — 의사결정 분기
지금 처음으로 1:1 음성 상담 서비스를 시작한다고 가정하면, 다음 분기로 결정한다.
| 조건 | 권장 |
|---|---|
| MVP, 트래픽 미검증, 출시 후 1~3 개월 안 측정 | 외부 서비스 — 운영 부담 0 이 우선 |
| 동시 호 ≥ 50, region 일치, Linux 운영자 1 인 이상 | self-host — 비용·latency 모두 우위 |
| 글로벌 사용자, 한국 외 region 트래픽 30 %+ | 외부 서비스의 GSLB — self-host 다중 region 운영 부담 큼 |
| 비-멱등 외부 연동(결제 등) 이 호 시작에 묶여 latency 가 critical | self-host 진지 검토 — 50~100ms 가 사용자 평가에 영향 |
요약: 외부 서비스 → 측정 → 조건 충족 시 self-host 전환 의 순서가 안전. 처음부터 self-host 로 시작하면 운영 부담을 측정 없이 짊어지게 된다.
함께 읽으면 좋은 글
- WebRTC STUN과 TURN, 언제 무엇을 — NAT 종류 × 성공률 매트릭스 — STUN/TURN 어느 쪽을 먼저 시도해야 하는지의 매트릭스
- WebRTC 연결의 6단계 — Offer/Answer부터 ICE Connected까지 — 본 글이 다룬 "ICE connectivity check" 가 정확히 어느 단계인지
- WebRTC 외부 TURN 서비스 vs self-host — 4축 의사결정 — 본 글 결정의 사전 분석. 4축(비용·latency·운영부담·지리적 분포) 의 정의
- WebRTC 디버깅 ‘끊긴다’ 현상이 보일 때 보는 5가지 — self-host 든 외부 서비스든 동일하게 적용되는 디버깅 순서
개정 이력
- 2026-05-XX — 최초 발행. AdSense W6 콘텐츠 정리 사이클의 long-form L2.
답글 남기기