Giới Thiệu: Chi Phí Lưu Trữ S3 — Khoản Chi "Ẩn" Đang Ăn Mòn Ngân Sách Cloud
Nói đến tối ưu chi phí cloud, hầu hết mọi người nghĩ ngay đến compute — GPU, EC2 instance, Kubernetes cluster. Nhưng thực tế thì chi phí lưu trữ chiếm tới 25-40% tổng hóa đơn AWS của nhiều tổ chức. Và Amazon S3, dịch vụ lưu trữ đối tượng phổ biến nhất thế giới, chính là nơi mà khoản lãng phí lớn nhất thường xảy ra.
Mình đã từng review hóa đơn AWS cho một startup và phát hiện họ đang trả gần 800 USD/tháng cho S3 — toàn bộ dữ liệu nằm trên S3 Standard, trong khi 70% là log file cũ hơn 6 tháng mà không ai đụng tới. Chuyện này phổ biến hơn bạn nghĩ.
Theo báo cáo năm 2026, chi tiêu cloud toàn cầu dự kiến đạt 1.03 nghìn tỷ USD, và khoảng 30-35% trong số đó bị lãng phí. Nếu bạn đang lưu hàng terabyte dữ liệu trên S3 Standard mà không có chiến lược phân tầng, nói thẳng là bạn đang đốt tiền.
Tin tốt là AWS cung cấp bộ công cụ khá mạnh để xử lý vấn đề này — từ S3 Intelligent-Tiering tự động chuyển dữ liệu sang tầng rẻ hơn, Lifecycle Policy để tự động hóa vòng đời dữ liệu, cho đến Storage Lens để xem tổng quan chi tiết. Trong bài viết này, mình sẽ hướng dẫn bạn cách áp dụng từng công cụ, kèm code để triển khai luôn.
1. Hiểu Rõ Các Storage Class Của S3 Và Bảng Giá 2026
1.1 Tổng Quan 7 Storage Class
AWS S3 có 7 storage class khác nhau, mỗi class phục vụ một mục đích riêng. Hiểu rõ đặc điểm từng class là bước đầu tiên (và quan trọng nhất) để tối ưu chi phí:
- S3 Standard: Dành cho dữ liệu truy cập thường xuyên. Giá $0.023/GB/tháng (US East). Phù hợp cho website, ứng dụng, content delivery.
- S3 Standard-IA (Infrequent Access): Cho dữ liệu ít truy cập nhưng cần lấy ngay khi cần. Giá khoảng $0.0125/GB/tháng. Có phí truy xuất và thời gian lưu trữ tối thiểu 30 ngày.
- S3 One Zone-IA: Tương tự Standard-IA nhưng chỉ lưu ở một Availability Zone. Giá khoảng $0.01/GB/tháng. Phù hợp cho dữ liệu có thể tái tạo được.
- S3 Glacier Instant Retrieval: Rẻ hơn Standard-IA tới 68%, truy xuất trong mili giây. Lưu trữ tối thiểu 90 ngày. Lý tưởng cho dữ liệu truy cập khoảng 1 lần/quý.
- S3 Glacier Flexible Retrieval: Giá $0.0036/GB/tháng. Thời gian truy xuất từ 1 phút đến 12 giờ. Phù hợp cho archive, backup, disaster recovery.
- S3 Glacier Deep Archive: Rẻ nhất — chỉ $0.00099/GB/tháng, rẻ hơn S3 Standard tới 96%. Truy xuất mất 12-48 giờ, lưu trữ tối thiểu 180 ngày. Dành cho dữ liệu lưu dài hạn 7-10+ năm.
- S3 Intelligent-Tiering: Tự động di chuyển object giữa các tầng dựa trên mẫu truy cập thực tế. Có phí monitoring $0.0025/1,000 object/tháng (cho object từ 128KB trở lên).
1.2 Bảng So Sánh Chi Phí Nhanh
Bảng dưới đây tóm tắt giá lưu trữ vùng US East - N. Virginia để bạn dễ so sánh:
| Storage Class | Giá/GB/tháng | Truy xuất | Lưu trữ tối thiểu |
|----------------------------|-------------|------------------|-------------------|
| S3 Standard | $0.023 | Mili giây | Không |
| S3 Standard-IA | $0.0125 | Mili giây | 30 ngày |
| S3 One Zone-IA | $0.01 | Mili giây | 30 ngày |
| Glacier Instant Retrieval | $0.004 | Mili giây | 90 ngày |
| Glacier Flexible Retrieval | $0.0036 | 1 phút - 12 giờ | 90 ngày |
| Glacier Deep Archive | $0.00099 | 12 - 48 giờ | 180 ngày |
| Intelligent-Tiering | Tự động | Tùy tầng | Không |
Ví dụ cụ thể nè: Nếu bạn đang lưu 10TB dữ liệu trên S3 Standard, hóa đơn hàng tháng là khoảng $235. Nếu 70% dữ liệu đó ít khi được truy cập và chuyển sang Glacier Instant Retrieval, chi phí giảm xuống còn khoảng $99 — tiết kiệm 58%. Con số đó nhân lên theo thời gian thì khá đáng kể.
1.3 Chi Phí "Ẩn" Bạn Cần Biết
Giá lưu trữ chỉ là một phần của bức tranh. Nhiều người bị "sốc" khi nhận hóa đơn vì quên tính các chi phí sau:
- Phí API request: Mỗi lần PUT, GET, LIST đều có phí. GET trên S3 Standard là $0.0004/1,000 request, nhưng trên Glacier Flexible Retrieval còn cộng thêm phí truy xuất nữa.
- Phí truy xuất dữ liệu (retrieval fee): Các class Glacier có phí truy xuất riêng — từ $0.01/GB (Glacier Instant Retrieval) đến $0.03/GB cho Glacier Flexible Retrieval (expedited). Chi phí này có thể vượt xa chi phí lưu trữ nếu bạn truy xuất archive thường xuyên.
- Phí lưu trữ tối thiểu: Xóa object từ Glacier Deep Archive trước 180 ngày? Bạn vẫn phải trả tiền cho đủ 180 ngày.
- Phí data transfer (egress): Di chuyển dữ liệu ra khỏi S3 tốn $0.09/GB cho 10TB đầu tiên ra internet. Cái này hay bị bỏ qua.
2. S3 Intelligent-Tiering: Giải Pháp "Thiết Lập Rồi Quên Đi"
2.1 Cơ Chế Hoạt Động
S3 Intelligent-Tiering là storage class thông minh nhất của AWS. Nó tự động di chuyển dữ liệu giữa các tầng truy cập dựa trên mẫu sử dụng thực tế — không ảnh hưởng hiệu năng và không mất phí truy xuất khi dữ liệu được chuyển ngược lên tầng cao hơn.
Về cơ bản, nó hoạt động qua các tầng sau:
- Frequent Access tier: Mặc định cho object mới upload. Giá tương đương S3 Standard.
- Infrequent Access tier: Tự động chuyển sau 30 ngày không truy cập. Tiết kiệm 40%.
- Archive Instant Access tier: Tự động chuyển sau 90 ngày không truy cập. Tiết kiệm 68%.
- Archive Access tier (tùy chọn): Cần kích hoạt thủ công, chuyển sau tối thiểu 90 ngày. Truy xuất trong vài phút đến vài giờ.
- Deep Archive Access tier (tùy chọn): Cần kích hoạt thủ công, chuyển sau tối thiểu 180 ngày. Tiết kiệm tới 95%.
Một con số ấn tượng: từ khi ra mắt năm 2018, khách hàng đã tiết kiệm hơn 6 tỷ USD nhờ S3 Intelligent-Tiering so với S3 Standard.
2.2 Khi Nào Nên Và Không Nên Dùng Intelligent-Tiering
Đây là phần mà nhiều người hay nhầm lẫn, nên mình liệt kê rõ ràng luôn.
Nên dùng khi:
- Mẫu truy cập dữ liệu không dự đoán trước được
- Object có kích thước từ 128KB trở lên
- Dữ liệu tồn tại lâu dài (trên 30 ngày)
- Bạn muốn tối ưu chi phí mà không cần phân tích mẫu truy cập phức tạp
Không nên dùng khi:
- Object nhỏ hơn 128KB — chúng luôn ở tầng Frequent Access nhưng bạn vẫn phải trả phí monitoring (lỗ ròng)
- Dữ liệu tồn tại ngắn hạn (dưới 30 ngày) hoặc bị ghi đè liên tục
- Bucket chứa hàng tỷ file nhỏ — phí monitoring cộng dồn khá đáng kể
- Mẫu truy cập hoàn toàn dự đoán được — lúc này dùng Lifecycle Policy kết hợp storage class cụ thể sẽ hiệu quả hơn
2.3 Cấu Hình Intelligent-Tiering Bằng Terraform
Dưới đây là cấu hình Terraform hoàn chỉnh để thiết lập S3 bucket với Intelligent-Tiering, bao gồm cả tầng Archive và Deep Archive:
# Tạo S3 bucket
resource "aws_s3_bucket" "data_lake" {
bucket = "my-company-data-lake-2026"
tags = {
Team = "data-engineering"
Environment = "production"
CostCenter = "CC-DATA-2026"
}
}
# Chuyển toàn bộ object mới sang Intelligent-Tiering
resource "aws_s3_bucket_lifecycle_configuration" "auto_tiering" {
bucket = aws_s3_bucket.data_lake.id
rule {
id = "transition-to-intelligent-tiering"
status = "Enabled"
transition {
days = 0
storage_class = "INTELLIGENT_TIERING"
}
}
rule {
id = "cleanup-multipart-uploads"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 7
}
}
}
# Kích hoạt Archive và Deep Archive tier
resource "aws_s3_bucket_intelligent_tiering_configuration" "full_tiering" {
bucket = aws_s3_bucket.data_lake.id
name = "FullTieringConfig"
tiering {
access_tier = "ARCHIVE_ACCESS"
days = 90
}
tiering {
access_tier = "DEEP_ARCHIVE_ACCESS"
days = 180
}
}
Lưu ý nhỏ: rule cleanup-multipart-uploads ở trên rất hay bị quên. Mình luôn thêm rule này vào mọi bucket — lý do sẽ nói kỹ hơn ở phần mẹo nâng cao.
2.4 Cấu Hình Bằng AWS CLI
Nếu bạn muốn áp dụng Intelligent-Tiering cho bucket đang chạy bằng AWS CLI thì đây:
# Bước 1: Tạo cấu hình Intelligent-Tiering cho bucket
aws s3api put-bucket-intelligent-tiering-configuration \
--bucket my-company-data-lake-2026 \
--id "FullTieringConfig" \
--intelligent-tiering-configuration '{
"Id": "FullTieringConfig",
"Status": "Enabled",
"Tierings": [
{
"Days": 90,
"AccessTier": "ARCHIVE_ACCESS"
},
{
"Days": 180,
"AccessTier": "DEEP_ARCHIVE_ACCESS"
}
]
}'
# Bước 2: Xác nhận cấu hình đã được áp dụng
aws s3api get-bucket-intelligent-tiering-configuration \
--bucket my-company-data-lake-2026 \
--id "FullTieringConfig"
2.5 Cấu Hình Bằng Python (Boto3)
Script Python dưới đây kích hoạt Intelligent-Tiering trên nhiều bucket cùng lúc — rất hữu ích nếu bạn có hàng chục hoặc hàng trăm bucket cần xử lý:
import boto3
def enable_intelligent_tiering(bucket_name, config_id="AutoTiering"):
"""
Kích hoạt S3 Intelligent-Tiering với Archive và Deep Archive
cho một bucket cụ thể.
"""
s3 = boto3.client("s3")
config = {
"Id": config_id,
"Status": "Enabled",
"Tierings": [
{"Days": 90, "AccessTier": "ARCHIVE_ACCESS"},
{"Days": 180, "AccessTier": "DEEP_ARCHIVE_ACCESS"},
],
}
s3.put_bucket_intelligent_tiering_configuration(
Bucket=bucket_name,
Id=config_id,
IntelligentTieringConfiguration=config,
)
print(f"Da kich hoat Intelligent-Tiering cho bucket: {bucket_name}")
def enable_tiering_all_buckets():
"""Kích hoạt Intelligent-Tiering cho toàn bộ S3 bucket trong account."""
s3 = boto3.client("s3")
buckets = s3.list_buckets()["Buckets"]
for bucket in buckets:
bucket_name = bucket["Name"]
try:
enable_intelligent_tiering(bucket_name)
except Exception as e:
print(f"Loi khi xu ly bucket {bucket_name}: {e}")
if __name__ == "__main__":
enable_tiering_all_buckets()
3. S3 Lifecycle Policy: Tự Động Hóa Vòng Đời Dữ Liệu
3.1 Lifecycle Policy Là Gì?
S3 Lifecycle Policy là bộ quy tắc tự động thực hiện hai loại hành động trên object trong bucket:
- Transition action: Tự động chuyển object sang storage class rẻ hơn sau một khoảng thời gian.
- Expiration action: Tự động xóa object khi hết hạn, giải phóng dung lượng và giảm chi phí.
Khác với Intelligent-Tiering (dựa trên mẫu truy cập thực tế), Lifecycle Policy hoạt động dựa trên tuổi của object — số ngày kể từ khi tạo. Cách này phù hợp khi bạn biết chắc vòng đời dữ liệu. Ví dụ: log file luôn "lạnh" sau 30 ngày, backup chỉ cần giữ 1 năm — những thứ có pattern rõ ràng.
3.2 Chiến Lược Lifecycle Cho Từng Loại Dữ Liệu
Mình tổng hợp lại các chiến lược lifecycle phổ biến nhất, dựa trên kinh nghiệm thực tế:
Log files (access log, application log):
- Ngày 0-30: S3 Standard (truy cập thường xuyên cho debug)
- Ngày 30-90: S3 Standard-IA (ít truy cập hơn)
- Ngày 90-365: S3 Glacier Instant Retrieval (giữ để compliance)
- Sau 365 ngày: Xóa hoặc chuyển sang Deep Archive
Backup và snapshot:
- Ngày 0-14: S3 Standard (cần truy cập nhanh để restore)
- Ngày 14-90: S3 Standard-IA
- Ngày 90-365: Glacier Flexible Retrieval
- Ngày 365-2555 (7 năm): Glacier Deep Archive
- Sau 7 năm: Xóa
Media files (ảnh, video do user upload):
- Nên dùng Intelligent-Tiering vì mẫu truy cập không dự đoán được — một số file viral, một số không ai xem lại. Không có cách nào biết trước.
3.3 Cấu Hình Lifecycle Policy Hoàn Chỉnh Bằng AWS CLI
Đây là ví dụ lifecycle policy tổng hợp cho bucket chứa nhiều loại dữ liệu. Bạn có thể copy và điều chỉnh theo nhu cầu:
aws s3api put-bucket-lifecycle-configuration \
--bucket my-production-bucket \
--lifecycle-configuration '{
"Rules": [
{
"ID": "log-lifecycle",
"Status": "Enabled",
"Filter": { "Prefix": "logs/" },
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER_IR" },
{ "Days": 365, "StorageClass": "DEEP_ARCHIVE" }
],
"Expiration": { "Days": 730 }
},
{
"ID": "backup-lifecycle",
"Status": "Enabled",
"Filter": { "Prefix": "backups/" },
"Transitions": [
{ "Days": 14, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER" },
{ "Days": 365, "StorageClass": "DEEP_ARCHIVE" }
],
"Expiration": { "Days": 2555 }
},
{
"ID": "tmp-cleanup",
"Status": "Enabled",
"Filter": { "Prefix": "tmp/" },
"Expiration": { "Days": 7 }
},
{
"ID": "cleanup-multipart-uploads",
"Status": "Enabled",
"Filter": {},
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": 7
}
},
{
"ID": "cleanup-old-versions",
"Status": "Enabled",
"Filter": {},
"NoncurrentVersionTransitions": [
{ "NoncurrentDays": 30, "StorageClass": "STANDARD_IA" },
{ "NoncurrentDays": 90, "StorageClass": "GLACIER" }
],
"NoncurrentVersionExpiration": {
"NoncurrentDays": 365,
"NewerNoncurrentVersions": 3
}
}
]
}'
Hai rule cuối cùng rất quan trọng nhưng thường bị bỏ qua:
- cleanup-multipart-uploads: Dọn dẹp multipart upload bị bỏ dở sau 7 ngày. Nói thật, không có lý do gì để giữ chúng lâu hơn — nếu upload chưa xong sau 7 ngày thì gần như chắc chắn nó đã bị abandon rồi.
- cleanup-old-versions: Nếu bạn bật versioning, các phiên bản cũ tích lũy âm thầm và có thể gấp đôi, gấp ba chi phí lưu trữ. Rule này giữ lại 3 phiên bản gần nhất và xóa phần còn lại sau 1 năm.
3.4 Cấu Hình Lifecycle Bằng Terraform
Nếu team bạn dùng Terraform (mình khuyến khích vì dễ quản lý hơn nhiều so với CLI cho production), đây là cấu hình tương đương:
resource "aws_s3_bucket_lifecycle_configuration" "production" {
bucket = aws_s3_bucket.production.id
# Rule cho log files
rule {
id = "log-lifecycle"
status = "Enabled"
filter {
prefix = "logs/"
}
transition {
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 90
storage_class = "GLACIER_IR"
}
transition {
days = 365
storage_class = "DEEP_ARCHIVE"
}
expiration {
days = 730
}
}
# Rule cho backup
rule {
id = "backup-lifecycle"
status = "Enabled"
filter {
prefix = "backups/"
}
transition {
days = 14
storage_class = "STANDARD_IA"
}
transition {
days = 90
storage_class = "GLACIER"
}
transition {
days = 365
storage_class = "DEEP_ARCHIVE"
}
expiration {
days = 2555
}
}
# Dọn dẹp multipart upload bỏ dở
rule {
id = "cleanup-multipart"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 7
}
}
# Quản lý phiên bản cũ
rule {
id = "manage-old-versions"
status = "Enabled"
noncurrent_version_transition {
noncurrent_days = 30
storage_class = "STANDARD_IA"
}
noncurrent_version_transition {
noncurrent_days = 90
storage_class = "GLACIER"
}
noncurrent_version_expiration {
noncurrent_days = 365
newer_noncurrent_versions = 3
}
}
}
4. S3 Storage Lens: Cái Nhìn Toàn Cảnh Về Chi Phí Lưu Trữ
4.1 Storage Lens Là Gì Và Tại Sao Bạn Cần Nó?
S3 Storage Lens là công cụ phân tích lưu trữ cho phép bạn nhìn tổng quan ở cấp tổ chức — drill down từ cấp organization xuống account, region, storage class, bucket, thậm chí đến cấp prefix. Nói cách khác, nó cho bạn biết tiền đang chảy đi đâu.
Cụ thể, Storage Lens cung cấp:
- Dashboard tương tác: Trực quan hóa xu hướng sử dụng và chi phí theo thời gian
- Đề xuất tối ưu: Xác định bucket không có lifecycle rule, bucket thiếu versioning, multipart upload bị bỏ dở
- Phân tích bubble: Tìm bucket đã "nguội lạnh" bằng cách so sánh dung lượng, tỷ lệ truy xuất, và kích thước object trung bình
4.2 Free Tier vs Advanced Tier
Free tier cung cấp 62 metric ở cấp bucket, với dữ liệu lịch sử 14 ngày. Nói thật thì đây đã đủ cho hầu hết nhu cầu phân tích cơ bản.
Advanced tier ($0.20/triệu object/tháng) thêm 136 metric, dữ liệu lịch sử 15 tháng, tích hợp CloudWatch, và hỗ trợ prefix aggregation. Bạn nên cân nhắc bật advanced tier cho những account có chi phí S3 lớn — khoản đầu tư nhỏ nhưng insight thu được rất có giá trị.
4.3 Tìm Bucket Lãng Phí Bằng Storage Lens
Đây là workflow mà mình hay dùng để tìm và xử lý bucket lãng phí:
Bước 1: Truy cập S3 Storage Lens dashboard trong AWS Console.
Bước 2: Dùng bộ lọc "Cost Optimization" để xem các metric liên quan đến chi phí.
Bước 3: Làm bubble analysis — tìm các bucket có:
- Tổng dung lượng lớn (trục X)
- Tỷ lệ truy xuất gần 0% (trục Y)
- Kích thước object trung bình lớn (kích thước bubble)
Những "quả bóng" to nằm ở góc dưới bên phải chính là nơi bạn đang lãng phí nhiều nhất.
Bước 4: Với mỗi bucket "nguội" tìm được, áp dụng một trong hai chiến lược:
- Dữ liệu vẫn cần giữ → chuyển sang Glacier hoặc Deep Archive
- Dữ liệu không còn cần → thiết lập expiration rule để xóa
4.4 Script Tự Động Phân Tích Chi Phí S3
Script Python dưới đây giúp bạn tự động quét toàn bộ S3 bucket và tìm cơ hội tối ưu. Mình dùng script tương tự chạy hàng tuần qua CloudWatch Events:
import boto3
from datetime import datetime, timedelta
def analyze_s3_buckets(region="ap-southeast-1"):
"""
Phan tich tat ca S3 bucket va tim co hoi toi uu chi phi.
"""
s3 = boto3.client("s3", region_name=region)
cloudwatch = boto3.client("cloudwatch", region_name=region)
buckets = s3.list_buckets()["Buckets"]
results = []
for bucket in buckets:
bucket_name = bucket["Name"]
try:
# Lay dung luong bucket tu CloudWatch
end_time = datetime.utcnow()
start_time = end_time - timedelta(days=7)
size_metric = cloudwatch.get_metric_statistics(
Namespace="AWS/S3",
MetricName="BucketSizeBytes",
Dimensions=[
{"Name": "BucketName", "Value": bucket_name},
{"Name": "StorageType", "Value": "StandardStorage"},
],
StartTime=start_time,
EndTime=end_time,
Period=86400,
Statistics=["Average"],
)
# Lay so luong request
request_metric = cloudwatch.get_metric_statistics(
Namespace="AWS/S3",
MetricName="AllRequests",
Dimensions=[
{"Name": "BucketName", "Value": bucket_name},
{"Name": "FilterId", "Value": "EntireBucket"},
],
StartTime=start_time,
EndTime=end_time,
Period=604800,
Statistics=["Sum"],
)
size_gb = 0
if size_metric["Datapoints"]:
size_gb = size_metric["Datapoints"][-1]["Average"] / (1024**3)
total_requests = 0
if request_metric["Datapoints"]:
total_requests = request_metric["Datapoints"][-1]["Sum"]
# Kiem tra lifecycle policy
has_lifecycle = True
try:
s3.get_bucket_lifecycle_configuration(Bucket=bucket_name)
except s3.exceptions.ClientError:
has_lifecycle = False
monthly_cost = size_gb * 0.023 # Gia S3 Standard
results.append({
"bucket": bucket_name,
"size_gb": round(size_gb, 2),
"weekly_requests": int(total_requests),
"has_lifecycle": has_lifecycle,
"estimated_monthly_cost": round(monthly_cost, 2),
})
except Exception as e:
print(f"Loi khi phan tich {bucket_name}: {e}")
# Sap xep theo chi phi giam dan
results.sort(key=lambda x: x["estimated_monthly_cost"], reverse=True)
print(f"\n{'Bucket':<40} {'Size (GB)':>10} {'Requests':>10} "
f"{'Lifecycle':>10} {'Cost/thang':>12}")
print("-" * 85)
for r in results:
lifecycle_status = "Co" if r["has_lifecycle"] else "KHONG"
print(f"{r['bucket']:<40} {r['size_gb']:>10} "
f"{r['weekly_requests']:>10} {lifecycle_status:>10} "
f"${r['estimated_monthly_cost']:>10}")
# Canh bao bucket khong co lifecycle
no_lifecycle = [r for r in results if not r["has_lifecycle"] and r["size_gb"] > 1]
if no_lifecycle:
print(f"\nCANH BAO: {len(no_lifecycle)} bucket khong co lifecycle policy!")
for r in no_lifecycle:
print(f" - {r['bucket']} ({r['size_gb']} GB, "
f"${r['estimated_monthly_cost']}/thang)")
if __name__ == "__main__":
analyze_s3_buckets()
5. Mẹo Nâng Cao: Tối Ưu Thêm 10-20% Chi Phí S3
OK, nếu bạn đã áp dụng Intelligent-Tiering và Lifecycle Policy rồi mà vẫn muốn cắt giảm thêm, thì đây là vài mẹo nâng cao.
5.1 Dọn Dẹp Multipart Upload Bị Bỏ Dở
Đây là một trong những nguồn lãng phí S3 phổ biến nhất nhưng ít ai để ý. Khi multipart upload bắt đầu nhưng không hoàn thành (do lỗi mạng, ứng dụng crash...), các phần đã upload vẫn nằm đó và tốn phí lưu trữ. Mình đã thấy trường hợp multipart upload "treo" chiếm tới vài trăm GB mà team không hề biết.
Luôn thêm rule AbortIncompleteMultipartUpload trong lifecycle policy — đã trình bày ở phần trước. Còn để kiểm tra nhanh xem bucket có multipart upload đang "treo" không:
aws s3api list-multipart-uploads --bucket my-bucket
5.2 Quản Lý Object Versioning Hiệu Quả
Versioning quan trọng để bảo vệ dữ liệu — điều đó không bàn cãi. Nhưng nếu không quản lý, các phiên bản cũ sẽ tích lũy âm thầm và có thể gấp đôi, gấp ba chi phí lưu trữ mà bạn không hề hay biết. Giải pháp đơn giản: luôn kết hợp versioning với NoncurrentVersionExpiration rule.
5.3 Sử Dụng S3 Object Tags Để Phân Tầng Chính Xác
Thay vì chỉ dựa vào prefix (đường dẫn), bạn có thể dùng object tag để áp dụng lifecycle rule linh hoạt hơn. Cách này đặc biệt hữu ích khi cùng một prefix chứa dữ liệu có yêu cầu lưu trữ khác nhau:
# Tag object khi upload
aws s3api put-object-tagging \
--bucket my-bucket \
--key reports/quarterly-2026-q1.pdf \
--tagging '{"TagSet": [{"Key": "retention", "Value": "7-years"}, {"Key": "data-class", "Value": "compliance"}]}'
# Lifecycle rule dua tren tag
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration '{
"Rules": [
{
"ID": "archive-compliance-data",
"Status": "Enabled",
"Filter": {
"Tag": { "Key": "data-class", "Value": "compliance" }
},
"Transitions": [
{ "Days": 90, "StorageClass": "GLACIER" },
{ "Days": 365, "StorageClass": "DEEP_ARCHIVE" }
]
},
{
"ID": "delete-temp-data",
"Status": "Enabled",
"Filter": {
"Tag": { "Key": "retention", "Value": "temporary" }
},
"Expiration": { "Days": 30 }
}
]
}'
5.4 Mới 2026: S3 Tables Với Intelligent-Tiering
Đầu năm 2026, AWS giới thiệu Intelligent-Tiering cho S3 Tables — tính năng tự động tối ưu chi phí cho các bảng Apache Iceberg trên S3. Nếu bạn đang chạy data lake hoặc analytics workload với Iceberg, tính năng này giúp dữ liệu "nguội" tự chuyển sang tầng rẻ hơn mà không cần chỉnh lifecycle thủ công. Khá tiện.
Ngoài ra, S3 Storage Lens giờ hỗ trợ export metric trực tiếp sang S3 Tables với định dạng Apache Iceberg, cho phép phân tích xu hướng lưu trữ bằng Athena, QuickSight, hoặc Redshift.
6. Checklist Tối Ưu Chi Phí S3 — Áp Dụng Ngay Hôm Nay
Nếu bạn chỉ có 30 phút, đây là 10 bước có impact cao nhất mà bạn nên làm trước:
- Bật S3 Storage Lens (free tier) để có cái nhìn tổng quan về sử dụng lưu trữ
- Xác định bucket không có lifecycle policy — đây thường là nơi lãng phí lớn nhất
- Thêm rule AbortIncompleteMultipartUpload (7 ngày) cho tất cả bucket
- Bật Intelligent-Tiering cho bucket có mẫu truy cập không dự đoán được
- Kích hoạt Archive và Deep Archive tier trong Intelligent-Tiering cho dữ liệu có thể truy xuất bất đồng bộ
- Thiết lập lifecycle rule cho log, backup, và dữ liệu tạm thời với lịch chuyển tầng rõ ràng
- Quản lý versioning: Thêm NoncurrentVersionExpiration rule nếu đã bật versioning
- Sử dụng object tag để phân loại dữ liệu theo mức độ quan trọng và thời gian lưu trữ
- Review hàng tháng: Kiểm tra Storage Lens dashboard để phát hiện xu hướng bất thường
- Tự động hóa: Chạy script quét bucket hàng tuần để phát hiện bucket lãng phí mới
Câu Hỏi Thường Gặp (FAQ)
S3 Intelligent-Tiering và Lifecycle Policy — nên dùng cái nào?
Câu trả lời ngắn: dùng cả hai. Hai công cụ này bổ sung cho nhau, không thay thế nhau. Dùng Intelligent-Tiering khi mẫu truy cập không dự đoán được — nó tự phân tầng dựa trên hành vi thực tế. Dùng Lifecycle Policy khi bạn biết chắc vòng đời dữ liệu — log file luôn "lạnh" sau 30 ngày chẳng hạn. Trong thực tế, nhiều tổ chức kết hợp cả hai: Lifecycle Policy chuyển object mới sang Intelligent-Tiering (ngày 0), rồi Intelligent-Tiering tự phân tầng từ đó.
Chuyển dữ liệu sang Glacier có mất dữ liệu không?
Không. Glacier chỉ thay đổi tầng lưu trữ, không xóa hay sửa đổi gì cả. Bạn hoàn toàn lấy lại được — khác biệt chính là thời gian truy xuất. Glacier Instant Retrieval mất vài mili giây, Glacier Flexible Retrieval mất 1 phút đến 12 giờ, Deep Archive mất 12-48 giờ. Lưu ý là có phí truy xuất riêng, nên hãy tính toán kỹ nếu bạn cần truy xuất thường xuyên.
Phí monitoring Intelligent-Tiering có đáng không?
Phí monitoring là $0.0025/1,000 object/tháng cho object từ 128KB trở lên. Với 1 triệu object, phí monitoring là $2.50/tháng. Nếu chỉ 30% dữ liệu chuyển sang Infrequent Access (tiết kiệm 40%), bạn tiết kiệm được nhiều hơn rất nhiều so với phí monitoring. Tuy nhiên, bucket có hàng tỷ file rất nhỏ (dưới 128KB) thì không đáng — file nhỏ không được tự động phân tầng nhưng vẫn bị tính phí monitoring.
Làm sao biết bucket nào đang lãng phí nhất?
Cách nhanh nhất: bật S3 Storage Lens (miễn phí) và dùng bộ lọc "Cost Optimization" để tìm bucket dung lượng lớn nhưng tỷ lệ truy xuất thấp. Bạn cũng có thể chạy script phân tích như trong bài này để quét tự động bucket không có lifecycle policy. Ngoài ra, AWS Cost Explorer cho phép lọc chi phí theo dịch vụ S3 và nhóm theo bucket name — nhìn rõ ngay bucket nào tốn nhiều nhất.
Lifecycle policy áp dụng được cho dữ liệu đã tồn tại không?
Được. Khi thêm lifecycle configuration vào bucket, các rule áp dụng cho cả object đã tồn tại lẫn object mới upload. Tuy nhiên, có độ trễ vài phút trước khi cấu hình mới có hiệu lực hoàn toàn. Amazon S3 chạy lifecycle rule mỗi ngày một lần, và sau lần chạy đầu tiên, nó sẽ đánh dấu tất cả object đủ điều kiện để chuyển tầng hoặc xóa.