동적 API라도 CloudFront를 앞단에 두면 사용자는 가장 가까운 엣지에서 TCP/TLS 연결을 끝내고, 엣지~서울 리전 구간은 불안정한 퍼블릭 인터넷 대신 AWS 전용 글로벌 백본을 탄다. 그 결과 대륙 간 왕복으로 생기던 초기 연결 지연(수백 ms)과 경로 불안정성을 줄일 수 있다.
2. 엣지에서 먼저 막는다
WAF를 ALB에 붙이면 공격 트래픽이 서울 리전까지 도달해 EC2·ALB 자원을 소모한 뒤에야 차단되지만, CloudFront를 두면 오리진에 닿기도 전에 사용자와 가까운 엣지에서 봇·스캐닝·DDoS를 원천 차단한다.
3. 캐싱·운영 이점
인증이 필요 없는 조회용 동적 API는 짧은 TTL과 stale-while-revalidate로 캐싱할 수 있고, 2024년 VPC Origin으로 오리진을 은닉하며 경로별 캐시 정책으로 정적·동적 리소스를 단일 도메인에서 서비스해 CORS 이슈를 없앤다.
일반적으로 알려진 아키텍처는 정적 리소스는 S3/Nginx + CloudFront로 캐싱하고, 동적 API는 캐싱이 필요 없거나 하면 안 되니 CloudFront 없이 ALB에 바로 붙이는 것이다. 백단에는 EC2를 두고 ALB가 로드밸런싱을 한다. 그런데 ALB를 단독으로 노출하면 세 가지 약점이 생긴다.
약점
내용
글로벌 성능
해외 유저 → 서울 리전까지 오는 퍼블릭망 자체가 불안정
보안
요청이 오리진(리전)까지 곧바로 도달
품질 편차
퍼블릭망은 ISP별로 품질 차이가 발생
이 약점들을 CloudFront를 앞단에 둠으로써 상쇄하고 성능·보안·운영 관점의 이점을 얻는다는 것이 영상 전체의 주제다.
⚠️ 캐싱을 전혀 쓰지 않는 동적 API라 하더라도 CDN의 가치는 캐싱이 아니라 네트워크 경로·보안 경계에서 나온다. 즉 'API는 캐싱할 필요가 없으니 CDN도 필요 없다'는 통념은 CDN의 이점을 캐싱 하나로만 좁게 본 데서 온 오해다.
▶️ 관련 스크립트
구조의 관성입니다. 정적 리소스는 CDN, 동적 API는 ALB. 이게 일반적으로 알려져 있는 아키텍처죠.
이렇게 ALB를 단독으로 연결했을 때 약점이 있습니다. 먼저 글로벌 지원, 해외 유저일 경우 유저로부터 서울 리전까지 오는 이 퍼블릭망 자체가 불안정해서 성능상 단점이 발생할 수 있습니다.
그리고 이 구간에서 보안적인 측면에서도 오리진까지 요청이 바로 들어오기 때문에 보안상 단점이 발생할 수 있습니다.
2. 글로벌 지연의 물리적 벽과 백본으로의 해소
서비스가 서울 리전에 있고 사용자가 해외에 있을 때, ALB를 바로 붙이면 불안정한 퍼블릭 구간을 왕복해야 한다. 문제는 데이터를 주고받기도 전에 연결 자체에 비용이 든다는 점이다. TCP 3-way Handshake와 TLS는 연결 수립을 위해 대륙 간 구간을 여러 번 왕복하고, 이 왕복 횟수가 곧 지연으로 누적된다. 퍼블릭 인터넷은 경로가 매번 달라질 수 있어 이 지연이 들쭉날쭉하다 — 이것이 '물리적인 벽'이다.
CloudFront를 두면 사용자는 자기 지역에서 가장 가까운 엣지로 연결되어 TCP/TLS 핸드셰이크를 그 짧은 구간에서만 끝낸다. 엣지~서울 리전 구간은 AWS 글로벌 백본이 담당한다.
성능의 핵심은 이 백본이다. 화자는 퍼블릭 인터넷을 국도(여러 ISP 망을 거치며 정체·우회·패킷 손실 발생)에, AWS 전용 백본을 전용 고속도로에 비유한다. 백본은 지터(jitter)가 낮은 최적화된 경로로 빠르고 안정적인 통신을 제공한다. (보충) TLS 1.3은 핸드셰이크가 1-RTT로 줄어 엣지에서 자동 적용 시 추가로 빨라진다.
⚠️ 지연은 대역폭이 아니라 '연결 수립을 위한 왕복 횟수 × RTT'에서 먼저 발생한다. CloudFront가 줄이는 것은 전송량이 아니라 사용자~오리진 사이의 물리적 왕복 거리, 즉 핸드셰이크 RTT다.
📝 적용 예시
물리적 지연 추정 예시 — 입력: 사용자~서울 리전 RTT가 약 200ms인 해외 접속. 적용: 연결 수립을 위해 TCP·TLS 핸드셰이크가 대륙 간 구간을 여러 차례 왕복. 결과: 환경에 따라 다르지만 데이터를 주고받기도 전에 약 300~800ms 내외의 초기 연결 지연이 발생할 수 있다. 퍼블릭 경로는 불안정해 매번 다르게 나온다.
▶️ 관련 스크립트
글로벌 지연의 물리적인 벽입니다. 서비스는 서울 리전에 있고 사용자는 해외에 있다고 가정하면, ALB를 바로 붙일 경우 해외에서 서울 리전까지 오는 불안정한 퍼블릭 구간을 왕복해야 합니다.
RTT가 200ms라면, 환경에 따라 다르겠지만 300에서 800ms 내외의 지연이 발생할 수 있습니다. 이건 데이터를 주고받기도 전에 발생하는 지연인 거죠.
TCP, TLS 연결이 이 구간에서만 이루어지고, CDN 서버와 서울 리전까지는 AWS의 글로벌 백본을 활용해서 안정적인 통신을 지원하게 됩니다.
성능 향상의 핵심은 AWS의 글로벌 백본 네트워크입니다. 일반 퍼블릭 인터넷은 국도에 비유할 수 있습니다. 수많은 ISP 통신사 망을 거쳐서 정체, 우회, 패킷 손실 등이 발생할 수 있죠.
AWS 전용 백본을 활용하면 CDN 엣지부터 서울 리전까지 AWS가 구축한 글로벌 네트워크 백본을 통해 빠르고 안정적인 통신을 할 수 있습니다.
3. 동적 API의 부분 캐싱과 stale-while-revalidate
네트워크 향상과 별개로, '동적'이라 불리는 API도 상당수는 부분 캐싱이 가능하다. 인증이 필요 없는 공용 조회용 API — 상품 목록, 버전 체크, 메타데이터 — 는 동적이지만 어느 정도 캐싱해도 되는 성격이다. 조회 위주 API에 그리 길지 않은 TTL만 줘도 큰 속도 향상을 얻는 경우가 많다.
CloudFront의 stale-while-revalidate(SWR) 옵션을 쓰면 캐시가 만료돼도 사용자에게는 즉시 캐시를 반환하고, 백그라운드에서 캐시를 갱신한다. 사용자 지연을 없애면서 데이터 신선도도 유지하는 운영 방식이다.
⚠️ 캐싱 가능 여부를 '동적/정적'이라는 라벨이 아니라 '인증이 필요한가, 조회 위주인가'라는 데이터 성격으로 판단해야 한다. stale-while-revalidate는 만료된 캐시를 사용자에게 즉시 돌려주면서 백그라운드에서 갱신해, 데이터 신선도와 사용자 지연이라는 상충하는 두 목표의 균형을 잡는 옵션이다.
📝 적용 예시
SWR 동작 예시 — 설정: max-age=10s, stale-while-revalidate=30s. 흐름: ① 캐시는 10초 동안 신선한(fresh) 상태로 그대로 사용된다. ② 10초가 지나 만료된 뒤 요청이 오면, 사용자에게는 일단 기존(stale) 응답을 즉시 반환해 지연을 없앤다. ③ 동시에 백그라운드에서 오리진을 호출해 실제 데이터 갱신이 이루어진다. 결과: 사용자는 항상 즉시 응답을 받고, 캐시는 비동기로 최신화된다.
▶️ 관련 스크립트
네트워크 향상뿐만 아니라, 일반적인 동적 API도 부분 캐싱을 해도 되는 경우가 상당히 많습니다.
인증이 필요 없는 공용 조회용 API, 상품 목록이나 버전 체크 같은 API들은 동적이지만 캐싱을 어느 정도 사용해도 되는 성격의 API들이죠. 메타데이터도 마찬가지고요.
stale-while-revalidate 옵션을 쓰면 캐시가 만료되어도 사용자에게는 즉시 반환하고 백그라운드에서 캐시를 업데이트해서, 데이터 신선도와 유저 지연을 최소화하는 형태로 캐시를 운영할 수 있습니다.
max-age는 10초, swr은 30초로 해서 10초 동안 신선도를 유지하다가, 사용자 요청이 오면 일단 즉시 반환해 지연을 없애고 백그라운드에서 실제 데이터 갱신이 이루어지는 거죠.
4. 엣지 보안: 공격을 오리진 도달 전 원천 차단
ALB에도 WAF(웹 방화벽)를 붙일 수는 있다. 그러나 이때 공격 트래픽은 서울 리전까지 도달한 뒤에야 차단된다 — 즉 이미 EC2와 ALB가 CPU를 소모하는 단계다. 차단은 되지만 서버 자원이 먼저 깎인다.
반면 CloudFront를 앞단에 두면 사용자와 가까운 엣지에서, 트래픽이 리전까지 오지도 않은 상태로 즉시 차단한다. 오리진 인프라에 닿기 전에 원천 봉쇄하는 것이다. 봇·스캐닝·DDoS 공격이 많은 API라면 인프라 보호 효율이 극명하게 달라진다.
⚠️ ALB+WAF와 CloudFront의 차이는 '막느냐 못 막느냐'가 아니라 '어디서 막느냐'다. 차단 지점이 오리진(리전)이냐 엣지냐에 따라, 공격을 흡수하며 소모되는 서버 자원의 양이 결정된다.
▶️ 관련 스크립트
그런데 이렇게 하면 공격 트래픽이 우리 서버 리전까지 와서야 막히게 됩니다. 이미 EC2와 ALB가 CPU를 먹고 있는 단계인 거죠.
반면 CloudFront를 앞단에 두면 현지 엣지에서, 리전까지 오지도 않은 상태에서 즉시 공격을 차단합니다.
5. 인프라 보호: 커넥션 풀링과 트래픽 흡수
엣지는 수만 개의 클라이언트 연결을 대신 받아주고, 오리진으로는 최적화된 적은 수의 연결만 전달한다. 커넥션 풀링과 Keep-Alive 설정 덕에 오리진 입장에서는 핸드셰이크 오버헤드가 거의 없고, 순간 트래픽이 폭주할 때도 서버가 훨씬 잘 버틴다.
⚠️ 엣지가 클라이언트 연결의 '완충 지대' 역할을 하므로, 오리진은 다수 클라이언트와 매번 핸드셰이크를 반복하지 않는다. 수만 개의 짧은 연결을 소수의 재사용 연결로 수렴시켜 오리진의 연결 처리 부담을 줄이는 것이 인프라 보호의 핵심이다.
▶️ 관련 스크립트
인프라 쪽도 이점이 있습니다. 엣지가 수만 개의 클라이언트 연결을 받아주고, 오리진으로는 최적화된 적은 수의 연결만 전달하게 되죠.
6. 운영 편의성: VPC Origin·오리진 은닉·단일 도메인
운영 관점의 이점도 크다.
기능
효과
VPC Origin (2024 출시)
Private ALB도 공용 인터넷 노출 없이 CloudFront와 연결 — 오리진의 완전한 은닉
최신 프로토콜 자동화
HTTP/3, TLS 1.3 같은 최신 프로토콜이 엣지에서 자동 적용 → 설정 한 번으로 글로벌 표준 준수
경로 기반 캐시 전략
동일 도메인에서 경로마다 다른 CDN 정책(예: 어떤 경로는 TTL=0) 적용 가능
경로 기반 전략 덕분에 정적 리소스와 동적 리소스를 하나의 도메인으로 서비스할 수 있고, 단일 도메인 운영이므로 CORS 같은 이슈가 사라진다.
⚠️ 캐시 정책은 도메인 단위가 아니라 경로 단위로 분리할 수 있다. 동일 도메인에서 정적 경로는 길게 캐싱하고 동적 경로는 TTL=0으로 두는 식의 혼합 운영이 가능하므로, 정적·동적을 굳이 다른 도메인으로 쪼개 CORS를 떠안을 필요가 없다.
▶️ 관련 스크립트
2024년에 출시된 VPC Origin, 이 기능으로 Private ALB도 공용 인터넷 노출 없이 CloudFront와 연결이 가능해졌죠.
오리진의 완전한 은닉이 가능해진 거죠. 그리고 HTTP/3, TLS 1.3 같은 최신 프로토콜도 다 엣지에서 자동 적용되기 때문에 설정 한 번으로 글로벌 표준을 따를 수 있습니다.
CloudFront를 쓰면 경로 기반으로 캐싱 전략을 세울 수 있죠. 도메인은 동일한 상태에서 경로만 CDN을 쓰고요.
어떤 경로에는 TTL을 0으로 하는 식으로, 동일 도메인에 대해 서로 다른 CDN 정책을 세울 수 있어서 정적 리소스와 동적 리소스를 하나의 도메인으로 서비스할 수 있습니다.
단일 도메인 운영으로 CORS 같은 이슈가 없는 거죠.
7. 의사결정 가이드: CloudFront vs ALB 단독
정답은 정해져 있지 않다. 아키텍처는 비즈니스 요구와 시스템 특성에 따라 선택하는 것이다. 다만 가이드는 제시할 수 있다.
CloudFront를 앞단에 두길 권장
ALB 단독이 더 합리적
해외 사용자가 접속하는 글로벌 서비스
거의 국내 사용자 위주 환경
강력한 봇·대규모 스캐닝 방어가 필요할 때
보안 요구사항이 낮은 경우
트래픽 급증이 빈번할 때
트래픽 규모가 작고 변화가 일정할 때
(실제 Slack은 CloudFront로 API 레이턴시를 많이 줄였다고 함)
구조를 단순화하고 비용을 최소화해야 할 때
규모가 크거나 해외 서비스까지 고려한다면 CloudFront를 붙이는 것을 권장한다.
⚠️ 이 표는 규칙이 아니라 판단 보조 가이드다. 아키텍처에는 고정된 정답이 없고, 사용자 분포·트래픽 패턴·보안 요구·비용/단순성 우선순위라는 시스템 특성에 따라 선택해야 한다.
▶️ 관련 스크립트
의사결정 가이드입니다. 정답이 정해진 건 아니죠. 아키텍처는 비즈니스 요구와 시스템 특성에 따라 선택해야 합니다.
해외 사용자가 접속하는 글로벌 서비스 운영 시 CloudFront를 쓰면 성능과 보안에서 많은 이점을 얻을 수 있습니다.
강력한 봇 스캐닝 같은 대규모 스캐닝을 방어해야 할 때, 그리고 트래픽이 급증하는 게 빈번할 때 CloudFront를 앞단에 두면 좋고요. 실제 Slack에서는 API 레이턴시를 많이 줄였다고 하네요.
거의 국내 사용자 위주 환경일 때, 트래픽 규모가 작고 변화가 일정할 때, 보안 요구사항이 낮은 경우, 구조를 단순화하고 비용을 최소화해야 할 때는 굳이 앞단에 CloudFront를 두지 않아도 됩니다.
8. 마무리 정리
화자의 결론은 두 가지다. 첫째, CloudFront를 쓰면 AWS 전용 백본을 사용하게 되며, 전용 백본은 (불안정한 퍼블릭 경로 대비) 항상 정답일 수 있다. 둘째, 리전에 닿기 전에 사용자와 가장 가까운 엣지에서 보안을 방어하는 것도 좋은 아키텍처다. 결국 캐싱하지 않는 동적 API라도 CDN을 앞단에 두면 성능·보안 측면에서 이득을 볼 수 있다는 것이 영상의 핵심 메시지다.
▶️ 관련 스크립트
결론입니다. CloudFront를 쓰면 전용 백본을 사용한다고 했죠. 전용 백본은 항상 정답일 수 있습니다.
그리고 리전에 닿기 전에 사용자단에 가장 가까운 엣지에서 보안을 방어하는 것도 좋은 아키텍처죠.
개발 가이드라인
해외 사용자가 접속하는 글로벌 서비스라면, 캐싱하지 않는 동적 API라도 CloudFront를 앞단에 둬 엣지에서 TCP/TLS를 종료하고 엣지~오리진 구간은 AWS 글로벌 백본을 태워 초기 연결 지연을 줄여라.
캐싱 가능 여부를 '동적/정적' 라벨이 아니라 '인증이 필요한가, 조회 위주인가'로 판단하라. 인증 없는 공용 조회 API(상품 목록·버전 체크·메타데이터)는 짧은 TTL만으로도 큰 속도 이득을 얻는다.
신선도와 지연을 동시에 잡아야 하면 stale-while-revalidate를 쓰라. 예: max-age=10s, stale-while-revalidate=30s — 만료 후에도 즉시 stale 응답을 주고 백그라운드에서 갱신한다.
봇·스캐닝·DDoS가 많은 API는 WAF를 ALB가 아니라 엣지(CloudFront) 단에서 적용해, 공격이 오리진 자원을 소모하기 전에 차단하라.
VPC Origin으로 Private ALB를 공용 인터넷 노출 없이 연결해 오리진을 은닉하고, 경로 기반 캐시 정책(정적은 길게, 동적은 TTL=0)으로 정적·동적을 단일 도메인에서 서비스해 CORS를 회피하라.
국내 위주·소규모·트래픽이 일정·보안 요구가 낮고 단순성과 비용이 우선이면 CloudFront 없이 ALB 단독 구성이 더 합리적이다.