#AWS#CloudFront#CDN#Caching#SWR#Cloud

AWS CloudFront에서의 무효화(invalidate) 및 SWR Pattern

AWS CloudFront에 SWR(Stale-While-Revalidate) 패턴 적용

AWS CloudFront 는 전 세계 엣지에 정적 파일을 캐싱해서 빠르게 제공한다.

이 기본 캐싱 정책 때문에 S3 + CloudFront로 컨텐츠를 배포하면,
수정사항이 생겼을 때 무효화(invalidation) 를 해줄 필요가 생긴다.

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


그래서, SWR(Stale-While-Revalidate) 패턴을 적용하는 과정을 알아보려고 한다.


☑️ SWR Pattern?


SWR은 “조금 낡은 데이터를 먼저 보여 주고, 뒤에서 몰래 최신화”하는 전략이다.

  1. 사용자가 페이지를 요청하면, 캐시된 콘텐츠를 즉시 전달
  2. 동시에 백그라운드에서 원본(S3)에 요청을 보내 최신 여부를 확인
  3. 변경이 있다면 캐시를 업데이트하고 다음 요청부터 바로 새로운 콘텐츠가 전달

즉, Cache-Control: max-age=10, stale-while-revalidate=60과 같은 헤더를 사용하면 10초 동안은 Fresh, 이후 60초까지는 Stale이 허용되고 그 사이에 CloudFront가 알아서 최신화해주는 전략이다.


☑️ 사용한 구성 요소


  • React: 정적 웹사이트 빌드
  • S3: 정적 사이트 호스팅
  • CloudFront: CDN 배포
  • AWS CLI / Console: 파일 업로드 및 캐시 정책 설정

☑️ 1. AWS CLI 사용


CI/CD 파이프라인에서 S3로 빌드 결과를 업로드할 때,

보통은 aws s3 sync 명령어로 빌드 파일을 올린다.

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

그런데 sync는 변경된 파일만 업로드하기 때문에, 캐시 헤더가 갱신되지 않는다.

캐시 정책을 바꾸려면 cp --recursive 명령어를 통해서 강제로 모든 파일을 덮어써야 한다.

항목synccp --recursive
기본 동작변경된 파일만 업로드모든 파일 강제 업로드
캐시 헤더 반영기존 헤더 유지새 헤더 적용
속도빠름느릴 수 있음
추천 상황자주 배포헤더 변경 필요할 때

☑️ 2. 캐시 헤더 설정


모든 파일을 새 헤더로 덮어쓴다.

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 값이 추출되지 않는다.


☑️ 3. CloudFront 캐시 정책 생성 (GUI)


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

상태 흐름

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

TTL 설정

  • 최솟값(Minimum TTL): 0
  • 기본값(Default TTL): 10
  • 최댓값(Maximum TTL): 70 초 (= max-age + stale-while-revalidate)


  • custom header도 추가해주고,


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


☑️ 4. 동작 확인


  1. 파일 업로드 후 curl -I https://<cloudfront-domain>/index.html
  2. 응답 헤더의 x-cache 값을 측정
x-cache의미
Miss from cloudfront캐시 첫 등록
Hit from cloudfrontTTL 내 응답 또는 SWR 허용 구간
RefreshHit from cloudfrontStale 상태에서 오리진의 304 응답으로 갱신

테스트 결과:

  • 처음 요청: Miss


  • 연속 요청: Hit


  • 70초 이상 요청이 없으면 RefreshHit, 이후 다시 Hit


  • S3에서 파일을 수정하면 Age(초) 값이 초기화


☑️ 5. 흐름 정리


시간대상태동작x-cache
0~10초Fresh캐시에서 즉시 응답Hit from cloudfront
10~70초Stale 허용Stale 응답 + 백그라운드 최신화Hit 또는 RefreshHit
70초 이후만료오리진에서 새로 가져옴Miss from cloudfront

☑️ 6. 무효화(invalidation)와 비교


관점SWR무효화
사용자 체감항상 빠른 응답새 버전 적용 전 잠깐 느려질 수 있음
운영헤더만 잘 관리하면 자동무효화 요청을 자동화해야 함
비용일반적인 요청 비용만 발생1,000건 초과 시 무효화 비용 부과