S3 비용 최대 80% 절감, Intelligent-Tiering 설정
S3 Intelligent-Tiering이 모든 버킷의 정답은 아니다. 서울 리전 단가로 손익분기 객체 크기를 계산하고, 라이프사이클 적용부터 검증, 티어가 안 내려가는 함정까지 정리했다.
S3 버킷의 청구서를 열어 보면 대부분 S3 Standard 한 줄이 차지하고 있다. 그런데 그 안의 데이터 중 지난 한 달 동안 한 번이라도 읽힌 건 얼마나 될까. 읽히지 않는 객체를 Intelligent-Tiering으로 바꾸면 조회 요금 없이 서울 리전 기준 GB당 월 $0.025가 $0.005까지 내려간다. 다만 객체마다 모니터링 요금이 붙기 때문에, 객체가 너무 작은 버킷에서는 오히려 돈이 더 나간다.
이 글은 어디까지가 이득이고 어디부터 손해인지 숫자로 가르고, 기존 버킷에 적용한 뒤 실제로 내려가는지 확인하는 순서로 정리했다. 단가는 2026년 10월 25일에 AWS 가격 데이터에서 직접 받은 서울(ap-northeast-2) 값이고, 동작 규칙은 AWS 공식 문서, 화면은 한국어 S3 콘솔 기준이다.
바쁘다면 이 세 가지만
- 평균 객체 크기가 256KB를 넘는 버킷이면 적용할 만하다. 그보다 작으면 모니터링 요금 때문에 남는 게 거의 없다.
- 버킷의 [관리] 탭에서 수명 주기 규칙 하나만 만들면 기존 객체와 새 객체가 모두 옮겨진다. 코드 수정은 필요 없다.
- 절감은 30일 뒤부터 보이기 시작해 90일째에 본 궤도에 오른다. 첫 달 청구서가 그대로여도 정상이다.
💸 어떻게 싸지나
Intelligent-Tiering(INTELLIGENT_TIERING)은 객체마다 마지막 접근 시점을 추적해서, 안 읽힌 기간에 따라 저장 티어를 자동으로 옮겨 주는 스토리지 클래스다. 한국어 콘솔에는 지능형 계층화로 표기된다. 처음 올리면 Frequent Access에서 시작하고, 클래스는 그대로인 채 안에서 티어만 바뀐다.
| 티어 | 내려가는 조건 | 서울 GB·월 |
|---|---|---|
| (비교) S3 Standard | - | $0.025 |
| Frequent Access | 업로드 직후, 접근하면 여기로 복귀 | $0.025 |
| Infrequent Access | 30일 연속 미접근 | $0.0138 |
| Archive Instant Access | 90일 연속 미접근 | $0.005 |
| Archive Access (옵션) | 설정한 일수 이상 미접근 (최소 90일) | $0.0045 |
| Deep Archive Access (옵션) | 설정한 일수 이상 미접근 (최소 180일) | $0.002 |
위 세 티어는 모두 밀리초 단위로 바로 읽힌다. 읽는 순간 객체는 Frequent Access로 올라오는데, 이때 조회 요금이 없다. Standard-IA나 Glacier 계열과 갈리는 지점이 여기다. 그쪽은 GB당 조회 요금과 최소 보관 기간(Standard-IA 30일)이 붙지만 Intelligent-Tiering은 둘 다 없다.
대가는 객체당 월 $0.0000025의 모니터링·자동화 요금(1,000개에 $0.0025)이다. 객체가 크면 티끌이고, 작으면 본전을 못 뽑는다.
🧮 손익분기는 객체 크기가 정한다
객체 하나가 아낄 수 있는 돈은 크기 × 단가 차이이고, 내야 하는 돈은 월 $0.0000025로 고정이다. 둘이 같아지는 크기가 손익분기다.
| 객체가 머무는 티어 | Standard 대비 GB당 월 절감 | 손익분기 객체 크기 |
|---|---|---|
| Infrequent Access | $0.0112 | 약 234KB |
| Archive Instant Access | $0.020 | 약 131KB |
평균 객체 크기가 수백 KB 이하인 버킷은 적용하지 않는 게 맞다.
128KB보다 작은 객체는 아예 모니터링 대상이 아니다. 수수료를 안 내는 대신 늘 Standard와 같은 Frequent Access 요금을 낸다. 애매한 건 128KB를 갓 넘긴 객체다. 128KB짜리는 Archive Instant Access까지 내려가도 한 달에 아끼는 돈이 약 $0.00000244로, 수수료 $0.0000025에 근소하게 모자란다.
📊 10TB 버킷으로 계산해 보면
10TB(10,240GB)에 객체 200만 개(평균 약 5.2MB)가 있고, 정상 상태의 티어 분포를 Frequent 15%, Infrequent 25%, Archive Instant 60%로 가정했다. 실측이 아니라 계산용 가정이다.
| 항목 | 월 비용 |
|---|---|
| S3 Standard 그대로 | $256.00 |
| Intelligent-Tiering 스토리지 | $104.45 |
| Intelligent-Tiering 모니터링 | $5.00 |
| Intelligent-Tiering 합계 | $109.45 |
| 최악: 전부 Frequent Access에 머물 때 | $261.00 |
정상 상태라면 57% 가까이 줄어든다. 이미 쌓인 객체를 옮기는 1회성 전환 요청 비용 $20은 월 절감액($147)의 7분의 1 수준이다. 반대로 데이터가 계속 읽혀 하나도 안 내려가도 손해는 월 $5(약 2%)에 그친다. 잃을 수 있는 돈의 상한은 낮고 아낄 수 있는 폭은 큰 구조다.
🛠️ 적용: 라이프사이클 규칙 하나로 기존 객체와 새 객체 모두
버킷에 수명 주기 규칙을 하나 걸면 이미 쌓인 Standard 객체도, 앞으로 올라올 객체도 모두 Intelligent-Tiering으로 옮겨진다. 애플리케이션 코드는 고칠 필요가 없다. 업로드는 지금처럼 Standard로 하고, 읽기도 그대로 GetObject로 하면 된다. 앞의 세 티어는 모두 밀리초 단위로 바로 읽히기 때문이다.
- [범용 버킷]에서 대상 버킷을 열고 [관리] 탭의 [수명 주기 규칙 생성]을 누른다.
- [수명 주기 규칙 이름]에
to-intelligent-tiering같은 이름을 넣는다. - 규칙 범위는 [하나 이상의 필터를 사용하여 이 규칙의 범위 제한]을 고르고 [접두사]에
logs/를 넣는다. 버킷 전체에 걸 거라면 [버킷의 모든 객체에 적용]을 고른다. - [최소 객체 크기 지정]을 체크하고
256KB를 넣는다. 옆에 262,144 bytes로 환산돼 표시되고, 입력값보다 큰 객체만 대상이 된다. 앞에서 구한 손익분기를 반영한 값이다.

- [수명 주기 규칙 작업]에서 [스토리지 클래스 간에 객체의 현재 버전 전환]을 체크한다. 요청당 전환 요금 안내가 함께 뜨는데, 아래 인지 체크박스를 체크해야 다음으로 넘어간다.
- [스토리지 클래스 전환 선택]에서 [지능형 계층화]를 고르고 [객체 생성 후 경과 기간(일)] 칸에
0을 넣는다. - 페이지 맨 아래 [규칙 생성]을 누른다. 만든 규칙은 [관리] 탭의 [수명 주기 규칙] 목록에 뜬다.

💡 규칙을 만들 때 알아둘 것
- 전환 시점: 경과 기간
0일은 생성 다음 날 자정(UTC, 한국 시간 오전 9시) 이후 전환 대상이 된다는 뜻이다. 새로 올린 객체는 그때까지 Standard에 머문다. - 전환 비용: 객체당 요청 한 번으로 잡혀 서울 기준 1,000건에 $0.01이다. 기존 객체는 한 번만 내지만 새 객체는 올라올 때마다 붙는다. 그래도 한 달에 10만 건을 올려야 $1이다.
- 작은 객체: 128KB 미만 객체는 기본값으로 전환되지 않는다(2024년 9월부터 기본 동작). 위 규칙은 이미 최소 크기 조건이 있어서 신경 쓸 것이 없다.
- 멀티파트 정리: 캡처에서 보이듯 객체 크기 필터를 건 규칙에는 [만료된 객체 삭제 마커 또는 완료되지 않은 멀티파트 업로드 삭제] 작업을 넣을 수 없다. 필요하면 규칙을 따로 만든다.
- 기존 규칙과 충돌: 같은 접두사에 만료 규칙이 이미 있는지 목록에서 먼저 본다. 한 객체가 여러 규칙의 대상이 되면 영구 삭제가 전환보다 우선한다.
🗄️ 아카이브 티어는 따로 켠다
Archive Access와 Deep Archive Access는 자동으로 켜지지 않는다. 버킷·접두사·태그 단위 구성을 따로 만들어야 한다.
- 대상 버킷의 [속성] 탭에서 [지능형 계층화 아카이브 구성]을 찾아 [구성 생성]을 누른다.
- [구성 이름]을 넣고 [하나 이상의 필터를 사용하여 이 구성의 범위 제한]을 고른 뒤 [접두사]에
logs/를 넣는다. - [상태]는 [활성화]로 둔다.
- [아카이브 규칙 작업]에서 [딥 아카이브 액세스 계층]만 체크하고 기간에
365를 넣은 뒤 [생성]을 누른다. 입력할 수 있는 범위는 180~730일이다.

Archive Access를 건너뛴 이유는 단가다. 서울 기준 Archive Access($0.0045)는 Archive Instant Access($0.005)보다 GB당 $0.0005 싸지만, 읽으려면 복원을 거쳐야 한다. 문서도 Archive Access는 Archive Instant Access를 건너뛰고 싶을 때만 켜라고 안내한다. 얻는 게 큰 쪽은 $0.002의 Deep Archive다.
아카이브 티어로 내려간 객체는 복원하기 전까지
GetObject가 실패한다. 앞에서 코드 수정이 필요 없다고 한 건 아카이브 티어를 켜지 않았을 때의 이야기다.
복원은 RestoreObject로 하고, 표준 복원 기준 Archive Access는 3~5시간, Deep Archive Access는 12시간 이내가 걸린다. 애플리케이션이 비동기로 읽을 수 있는 데이터에만 켠다.
✅ 검증: 옮겨졌나, 내려가고 있나
🔎 클래스 전환: 객체 목록
S3 콘솔에서 logs/ 아래로 들어가면 목록에 [스토리지 클래스] 열이 있다. 전환 전 객체는 아래처럼 Standard로 나오고, 전환이 끝나면 Intelligent-Tiering으로 바뀐다. 수명 주기 규칙은 비동기로 돌기 때문에 규칙을 만든 직후에는 Standard 그대로일 수 있다. 하루 뒤에 다시 본다.

문제는 이 열이 티어가 바뀌어도 늘 Intelligent-Tiering이라는 점이다. 클래스는 그대로 두고 안에서 티어만 옮겨 다니기 때문이다. 티어 분포는 아래 두 곳에서 본다.
📈 티어별 용량: CloudWatch
CloudWatch 콘솔에서 리전을 서울로 맞추고, 지표 화면에서 AWS/S3 네임스페이스의 BucketName, StorageType 조합을 연다. BucketSizeBytes 지표를 버킷과 StorageType별로 체크하면 티어별 용량이 바이트 단위 그래프로 나온다.
| StorageType 값 | 티어 |
|---|---|
IntelligentTieringFAStorage | Frequent Access |
IntelligentTieringIAStorage | Infrequent Access |
IntelligentTieringAIAStorage | Archive Instant Access |
IntelligentTieringAAStorage | Archive Access (켰을 때) |
IntelligentTieringDAAStorage | Deep Archive Access (켰을 때) |
이 지표는 하루에 한 번 갱신되고, Intelligent-Tiering 객체가 하나도 없는 동안에는 목록에 나타나지 않는다.
📄 객체 단위: S3 Inventory
버킷의 [관리] 탭에서 [인벤토리 구성 생성]을 누르고, [추가 메타데이터 필드]에서 [크기]와 [Intelligent-Tiering: 액세스 계층]을 체크한다. 목적지 버킷과 보고 주기, 출력 형식을 정하고 [생성]을 누르면 된다. 첫 리포트는 최대 48시간 뒤에 나온다.

리포트에는 객체마다 FREQUENT, INFREQUENT, ARCHIVE_INSTANT_ACCESS 같은 값이 찍혀서, Athena로 어떤 접두사가 안 내려가는지 바로 짚을 수 있다. [Intelligent-Tiering: 참조 날짜]까지 켜 두면 마지막 접근으로 잡힌 날짜도 함께 나온다.
⏳ 언제부터 줄어드나
적용 직후에는 숫자가 하나도 안 변한다. 전환일부터 30일이 지나야 Infrequent로, 90일이 지나야 Archive Instant Access로 내려간다.
오래전에 올려 한 번도 안 읽은 객체도 예외가 아니다. 전환된 날을 기준으로 미접근 기간을 새로 센다. 그래서 한 달 뒤 청구서가 그대로라고 설정이 잘못된 건 아니다. 절감은 두 번째 달에 보이기 시작하고 90일째에 본 궤도에 오른다.
🚧 티어가 안 내려가는 경우
🔁 객체를 계속 읽는 작업이 있다
가장 흔한 원인은 접근의 정의다. 아래 왼쪽에 해당하는 요청이 오면 타이머가 처음으로 돌아가거나 객체가 Frequent Access로 올라간다.
| 접근으로 친다 | 접근으로 안 친다 |
|---|---|
GetObject, PutObject, RestoreObject | HeadObject |
CopyObject의 원본 객체 | ListObjectsV2 같은 목록 조회 |
| 콘솔에서 다운로드 | 태그 조회 |
전체 객체를 주기적으로 읽어 가는 백신 검사, 체크섬 검증 잡, 통째 복사 스크립트가 하나라도 돌고 있으면 그 접두사는 영원히 Frequent Access에 머문다. 비용이 안 줄면 설정보다 이런 잡부터 찾아본다.
🗂️ 버저닝을 켠 버킷
위 규칙은 현재 버전에만 적용된다. 이전 버전은 같은 규칙 화면에서 [스토리지 클래스 간에 객체의 이전 버전 전환]을 따로 체크해야 한다. Intelligent-Tiering 클래스로 남은 이전 버전도 객체 하나하나가 모니터링 요금 대상이라(Standard에 있는 이전 버전에는 붙지 않는다), 오래된 버전이 쌓이는 버킷은 전환보다 [객체의 이전 버전 영구 삭제]로 정리하는 편이 싸다.
🙅 굳이 쓰지 않아도 되는 데이터
업로드 후 30일 안에 지우는 임시 파일은 티어가 내려갈 틈이 없다. Standard에 두고 만료 규칙만 건다. 객체 수가 1억 개를 넘는 버킷은 모니터링 요금만 월 $250($0.0000025 × 1억)이다. 더 이상 읽지 않을 것이 분명하다면 Glacier 계열로 직접 보내는 쪽을 따져 볼 만하다.
📋 적용 전 체크리스트
- 접두사별 평균 객체 크기가 256KB 이상인지 확인한다. S3 Inventory의 [크기] 필드로 구한다.
- 객체를 전부 읽어 가는 배치·검사 잡이 있는지 확인한다.
- [관리] 탭의 [수명 주기 규칙] 목록에서 같은 접두사에 걸린 기존 규칙, 특히 만료 규칙이 있는지 본다.
- 아카이브 티어를 켤 거라면 애플리케이션이 복원 대기를 견딜 수 있는지 확인한다.
관련 글
PHP2Shell 취약점 CVE-2026-109618 원리·공격·방어
PHP 5.4부터 8.5.11까지 전부 걸린 인증 없는 RCE, PHP2Shell. 두 CVE가 어디서 터지는지, 왜 mod_php가 가장 위험한지, 패치·임시 완화·침해 점검을 명령어와 함께 정리했다.
Aurora PostgreSQL 15→16 Blue/Green 업그레이드
Aurora PostgreSQL 15를 Blue/Green으로 16에 올리며 세 번 실패한 원인(논리 복제 워커 수)과 해결, 사전 점검부터 그린 검증·스위치오버·사후 정리까지 콘솔 화면 기준으로 정리했다.
애드센스 네 번째 반려 뒤 글 22개를 보류했다 — 재신청 대기 중
8월부터 네 차례 반려된 애드센스 심사. 재신청 전 공개 글의 수치·출처와 사진 사용 조건을 다시 점검하고 있다. 10월 15일 현재 심사 결과는 아직 없다.