[Cloud] CloudFront의 캐싱 ( 무효화 / SWR Pattern )


CloudFront에 SWR Pattern 적용



CloudFront의 기본 캐시 정책 때문에, S3 등으로 웹페이지를 배포했을때, 수정사항이 생기면 일반적으로 무효화를 해줄 필요가 생긴다.

그런데, 무효화는 조건부 비용이 붙는다.

그래서 SWR Pattern을 CloudFront에 적용하는 과정을 알아보려고 한다.

SWR(Stale-While-Revalidate)는 사용자에게 빠른 응답을 제공하며, 복구 방식으로 최신 데이터를 검사하고 자동 갱신하는 캐시 옵션이다.

현재 사용중인 파일이 존재하면, TTL(max-age) 기간이 지나도 웹서버는 stale 데이터를 여전히 보내고, 뒤장에서 자동으로 조건부 요청 (If-Modified-Since / ETag) 을 사용해 최신화한다.

CloudFront에서 SWR을 적용하면, 사용자는 느리지 않고, 최신 컴퓨터 데이터가 나오면 자동으로 업데이티를 받게 된다.

SWR은 정상적인 Cache-Control 헤더 값 (ex. max-age=10, stale-while-revalidate=60)과, CloudFront 캐시 정체에서 해당 헤더를 유효하게 하는 설정이 업데이티 조건이 된다.

이를 통해 자동 최신화가 되는 모든 형태의 정적 캐시 구조를 구축할 수 있다.

✔️ 사용 기술

  • React - 웹페이지 생성
  • AWS S3 - 웹페이지 배포용
  • AWS CloudFront - CDN 배포
  • AWS CLI & GUI - 버킷 업로드 & 정책 생성

✔️ 웹페이지 구성

  • react로 웹페이지 생성, 빌드.
  • s3 생성, 정책 생성, 정적 사이트 호스팅.
  • CloudFront와 연결, 초기 Cache 정책은 Default.
  • 빌드파일 업로드

aws s3 sync build/ s3://<bucket-name> --acl public-read

빌드파일을 새로 업로드해도, s3의 웹사이트에만 반영이 될 뿐 CloudFront에는 변화가 없다. 기본적으로 캐싱을 하기 때문.

이제는 Cache-control 헤더를 포함해서 업로드를 해서 테스트한다. 캐시 헤더 변경이 필요하기때문에, cp 명령어를 사용한다.

항목synccp --recursive
기본 동작변경된 파일만 업로드모든 파일 무조건 업로드
캐시 헤더 적용❌ 기본적으로 새 헤더가 적용되지 않음 (변경 없으면 skip)✅ 모든 파일에 강제로 헤더 적용
성능빠름느릴 수 있음 (항상 전체 업로드)
권장 용도자주 배포할 때캐시 헤더 변경이 필요할 때



aws s3 cp build/ s3://swr-pattern-bucket-s3/ \
  --recursive \
  --cache-control "max-age=10, stale-while-revalidate=60" \
  --acl public-read

✔️ 헤더 적용 확인

PS C:\Users\admin\Desktop\react-swr-demo> aws s3api head-object --bucket swr-pattern-bucket-s3 --key index.html
>>
{
    "AcceptRanges": "bytes",
    "LastModified": "2025-07-24T07:21:59+00:00",
    "ContentLength": 644,
    "ETag": "\"92ed791677aab7efc06ae542ecdb82f3\"",
    "CacheControl": "max-age=10, stale-while-revalidate=60", // ✅
    "ContentType": "text/html",
    "ServerSideEncryption": "AES256",
    "Metadata": {}
}

CloudFront의 default 캐시 값이 적용되어있어서, x-cache 값이 추출되지 않는다.

헤더 적용 이후에 TTL 10초, 60초를 적용하기 위해서 CloudFront에서 0 ~ 10 ~ 70 의 SWR 정책을 생성해준다.

  • fresh 상태: 0~10초
  • stale 상태 허용: 10~70초

캐시 정책 생성 (GUI)

  • TTL 설정
    • 최솟값: 0
    • 기본값: 10
    • 최댓값: 70

custom header도 추가해주고,

CloudFront에 만들어준 캐시 정책을 적용해준다.

다시 cp명령어로 s3 상태를 업데이트하고 curl명령어를 통해서 상태를 확인한다.

curl -I https://<your-cloudfront-url>/index.html
x-cache 값의미
Hit from cloudfrontTTL 내 or stale 응답
RefreshHit from cloudfrontstale 상태 → 오리진 304 응답
Miss from cloudfront캐시 없음 or 만료됨 → 오리진에서 새로 가져옴

초기상태는 아래와 같이 x-cache 값이 Miss fron cloudfront가 출력된다.


기본적으로 요청을 보내면 아래와 같이 Hit from cloudfront 값이 출력되는데,


아래처럼 요청을 70초 이상 ( Max TTL ) 보내지 않으면 RefreshHit from cloudfront, 후에 다시 요청하면 Hit from cloudfront 을 출력받을 수 있다.


Hit from cloudfront 상태에서, s3에 수정사항을 적용하면 age 값이 10에서 다시 1로 돌아간다. (Min TTL)

✔️ 시간 순

시간상태동작x-cache
0~10초Fresh TTL캐시에서 응답, 오리진 무시Hit from cloudfront
10~70초SWR (stale allowed)stale 응답 + 오리진에 조건부 요청Hit 또는 RefreshHit
70초 이후TTL + SWR 만료오리진에서 새로 가져옴Miss from cloudfront

✔️ SWR Pattern VS 무효화

관점SWR무효화
응답속도매우 빠름느릴 수 있음 (무효화 후 첫 요청은 S3)
운영 자동화좋음 (build 시 header만 잘 설정)❌ 배포 자동화에 추가 작업 필요
유저 경험아주 부드럽게 최신화강제 새로고침 또는 잠깐 이전 버전 보임
비용요청 기준 (일반적)무효화 요청 1,000건 초과 시 유료