Quay lại bài viết
9 thg 5, 2026
9 min read

S3 Lifecycle Rules: Tự động tối ưu chi phí lưu trữ

Tự tay di chuyển objects giữa các storage class giống như phân loại thư bằng tay mỗi ngày — ban đầu thì ổn, nhưng không scale được.

Trong thực tế, bạn hiếm khi chọn một storage class rồi để mãi. Data thường hot khi mớicold theo thời gian — logs được query liên tục trong tuần đầu, user uploads được xem nhiều trong tháng đầu, rồi dần bị quên lãng.

S3 Lifecycle Rules cho phép bạn định nghĩa các transition tự động giữa các storage class dựa trên tuổi của object. Bạn cấu hình rules ở cấp bucket, và S3 xử lý phần còn lại — không cần cron jobs, không scripts, không can thiệp thủ công.

Nếu bạn chưa quen với các S3 storage class và trade-offs của chúng, hãy đọc S3 Storage Classes: Chọn đúng class cho dữ liệu của bạn trước.


Lifecycle Rules hoạt động như thế nào

Một lifecycle rule bao gồm:

Các ràng buộc quan trọng:

Nếu bạn cần objects tự động di chuyển hai chiều (xuống khi không truy cập, lên lại khi được truy cập), hãy dùng Intelligent-Tiering thay vì lifecycle rules. Lifecycle rules phù hợp nhất khi access pattern có thể dự đoán và giảm dần theo thời gian.


Ví dụ: Shopify Analytics Pipeline

Bài toán: Bạn đang thiết kế storage layer cho 1 analytic pipeline, để đơn giản hoá, bạn chỉ tập trung vào 1 metrics là product clicks

Hệ thống của bạn là một hệ thống analytics cho các store owner trên Shopify có thể phân tích các số liệu liên quan tới product clicks như conversion rate, click through rate, …

Storefront của mỗi store stream các product click events qua Kinesis Data Firehose vào S3 bucket dưới dạng raw data. AWS Glue chạy ETL jobs để clean, deduplicate, và aggregate raw data thành các bảng có cấu trúc trên S3.

Store owners truy cập dashboard chạy bằng AWS Athena để query processed data. Dashboard có các ràng buộc sau:

Pipeline tạo ra 3 loại dữ liệu trên S3, mỗi loại có lifecycle khác nhau:

{ "Rules": [ { "ID": "RawStreamData", "Status": "Enabled", "Filter": { "Prefix": "raw/" }, "Transitions": [ { "Days": 7, "StorageClass": "STANDARD_IA" }, { "Days": 90, "StorageClass": "GLACIER_FLEXIBLE_RETRIEVAL" }, { "Days": 365, "StorageClass": "DEEP_ARCHIVE" } ], "Expiration": { "Days": 1095 } }, { "ID": "ProcessedData", "Status": "Enabled", "Filter": { "Prefix": "processed/" }, "Transitions": [ { "Days": 180, "StorageClass": "STANDARD_IA" }, { "Days": 365, "StorageClass": "GLACIER_IR" } ], "Expiration": { "Days": 1095 } }, { "ID": "AthenaQueryResults", "Status": "Enabled", "Filter": { "Prefix": "athena-results/" }, "Expiration": { "Days": 7 } } ] }

Raw stream data (raw/)

Kinesis giao raw JSON/Parquet files vào đây. Glue đọc chúng trong vài ngày đầu để chạy ETL.

Processed data (processed/)

Đây là data mà Athena query cho dashboard của store owner — storage class ảnh hưởng trực tiếp đến tốc độ dashboard.

Không chuyển processed data xuống Glacier Flexible Retrieval trở xuống — Athena không thể query objects ở các class đó mà không restore thủ công trước, sẽ làm hỏng trải nghiệm dashboard.

Athena query results (athena-results/)

Athena lưu kết quả mỗi query vào S3. Đây là data hoàn toàn tạm thời — bất kỳ query nào cũng có thể chạy lại. Xóa sau 7 ngày — không cần chuyển sang class rẻ hơn, cứ expire luôn.


Ước tính chi phí

Giả sử platform phục vụ ~500 stores đang hoạt động, tổng cộng tạo ra 50 GB/ngày raw event data, và Glue tạo ra 10 GB/ngày processed data. Dưới đây là chi phí ở trạng thái ổn định sau 2 năm:

Giá S3 storage (us-east-1):

Storage ClassGiá per GB/tháng
S3 Standard$0.023
S3 Standard-IA$0.0125
Glacier Instant Retrieval$0.004
Glacier Flexible Retrieval$0.0036
Deep Archive$0.00099

Chi phí storage

Raw data (50 GB/ngày):

Giai đoạnClassDung lượngChi phí/tháng
Ngày 0–7Standard350 GB$8.05
Ngày 7–90Standard-IA4,150 GB$51.88
Ngày 90–365Glacier Flexible13,750 GB$49.50
Ngày 365–1095Deep Archive36,500 GB$36.14
Tổng54,750 GB$145.57

Không dùng lifecycle (toàn bộ Standard): 54,750 GB × $0.023 = $1,259.25/tháng — tiết kiệm 88%

Processed data (10 GB/ngày):

Giai đoạnClassDung lượngChi phí/tháng
Ngày 0–180Standard1,800 GB$41.40
Ngày 180–365Standard-IA1,850 GB$23.13
Ngày 365–730Glacier IR3,650 GB$14.60
Tổng7,300 GB$79.13

Không dùng lifecycle (toàn bộ Standard): 7,300 GB × $0.023 = $167.90/tháng — tiết kiệm 53%

Chi phí retrieval

Standard-IA và Glacier tính thêm retrieval fee per GB khi Athena scan data:

Storage ClassRetrieval Fee per GB
S3 StandardMiễn phí
S3 Standard-IA$0.01
Glacier Instant Retrieval$0.03
Glacier Flexible Retrieval$0.01 (Standard), $0.03 (Expedited)

Giả định dựa trên usage pattern của dashboard:

Loại dataClassRetrievedChi phí
RawStandard-IA100 GB$1.00
RawGlacier Flexible50 GB$0.50
ProcessedStandard-IA300 GB$3.00
ProcessedGlacier IR100 GB$3.00
Tổng$7.50

Tổng cộng

Có LifecycleToàn StandardTiết kiệm
Storage$224.86$1,427.31$1,202.45
Retrieval$7.50$0.00-$7.50
Tổng$232.36$1,427.31$1,194.95 (84%)

Tương đương ~$14,340 tiết kiệm mỗi năm — không ảnh hưởng gì đến trải nghiệm dashboard của store owners. 6 tháng hot window vẫn ở Standard với zero retrieval fee, trong khi data cũ hơn dần chuyển sang các class rẻ hơn mà vẫn hỗ trợ Athena query instant.


Kết hợp Lifecycle Rules với Object Tagging

Lifecycle rules có thể filter không chỉ theo prefix, mà còn theo S3 Object Tags. Điều này mở ra các pattern mạnh mẽ — như cung cấp các storage tier khác nhau dựa trên gói subscription của khách hàng.

Use case: Nâng cấp gói Premium

Tiếp tục ví dụ Shopify analytics — giả sử bạn muốn upsell gói premium với dashboard performance nhanh nhất cho toàn bộ dữ liệu lịch sử (không mất retrieval fee, không tăng latency cho data cũ).

Cách tiếp cận:

  1. Mặc định tag tất cả objects với plan=basic
  2. Cấu hình lifecycle rules chỉ transition objects có tag plan=basic:
{ "Rules": [ { "ID": "BasicPlanProcessed", "Status": "Enabled", "Filter": { "And": { "Prefix": "processed/", "Tags": [{ "Key": "plan", "Value": "basic" }] } }, "Transitions": [ { "Days": 180, "StorageClass": "STANDARD_IA" }, { "Days": 365, "StorageClass": "GLACIER_IR" } ] } ] }
  1. Khi store upgrade lên premium → tag objects thành plan=premium → objects không match rule nữa → giữ mãi ở Standard
  2. Với objects đã bị transition sang class rẻ hơn → copy lại về Standard

Triển khai

Khi store owner upgrade, bạn cần tag tất cả objects và copy những objects đã bị transition về Standard:

import { S3Client, ListObjectsV2Command, PutObjectTaggingCommand, CopyObjectCommand, } from '@aws-sdk/client-s3' import pLimit from 'p-limit' const s3 = new S3Client({ region: 'us-east-1' }) const BUCKET = 'your-analytics-bucket' const CONCURRENCY = 50 interface UpgradeResult { tagged: number copied: number errors: string[] } async function upgradeStorePlan(storeId: string): Promise<UpgradeResult> { const prefix = `processed/store_id=${storeId}/` const limit = pLimit(CONCURRENCY) const result: UpgradeResult = { tagged: 0, copied: 0, errors: [] } let continuationToken: string | undefined do { const listResponse = await s3.send( new ListObjectsV2Command({ Bucket: BUCKET, Prefix: prefix, ContinuationToken: continuationToken, }) ) const objects = listResponse.Contents ?? [] await Promise.all( objects.map((obj) => limit(async () => { const key = obj.Key! try { await s3.send( new PutObjectTaggingCommand({ Bucket: BUCKET, Key: key, Tagging: { TagSet: [{ Key: 'plan', Value: 'premium' }] }, }) ) result.tagged++ if (obj.StorageClass && obj.StorageClass !== 'STANDARD') { await s3.send( new CopyObjectCommand({ Bucket: BUCKET, CopySource: `${BUCKET}/${key}`, Key: key, StorageClass: 'STANDARD', MetadataDirective: 'COPY', TaggingDirective: 'COPY', }) ) result.copied++ } } catch (err) { result.errors.push(`${key}: ${(err as Error).message}`) } }) ) ) continuationToken = listResponse.NextContinuationToken } while (continuationToken) return result }

Các điểm quan trọng:

Chi phí upgrade 1 store

Giả sử 1 store với 2 năm data, 20 MB/ngày (10 GB/ngày ÷ 500 stores):

Giai đoạnClass hiện tạiDung lượngRetrieval Fee
Ngày 0–180Standard3.6 GB— (đã ở Standard)
Ngày 180–365Standard-IA3.7 GB$0.037
Ngày 365–730Glacier IR7.3 GB$0.219
14.6 GB$0.256

Chi phí S3 requests (ListObjects + CopyObject + PutObjectTagging) cho ~730 objects: < $0.02

Tổng chi phí upgrade 1 store: ~$0.28 — chi phí một lần, loại bỏ hoàn toàn retrieval fee cho dashboard của store đó.

Để so sánh, nếu không copy mà để premium store query data trên Standard-IA và Glacier IR, retrieval fees tích lũy ~$0.11/tháng. Chỉ sau 3 tháng, tổng retrieval fees đã vượt chi phí copy 1 lần. Copy ngay khi upgrade luôn là lựa chọn rẻ hơn.

Liên quan