2026-07-16 · 8 min
Cost Optimization AWS 100 Juta/Bulan → 60 Juta
Lima bulan lalu, klien enterprise Indonesia (e-commerce + logistics, 6 juta pengguna aktif, traffic puncak Lebaran 12x baseline) datang dengan bill AWS yang baru tembus Rp 100 juta/bulan ($6.300). Growth bisnis 22% YoY, cost AWS growth 41% YoY. CFO mulai panas.
Lima bulan optimasi, bill jadi Rp 60 juta/bulan. Saving Rp 40 juta/bulan, ~$30k/tahun. Share metodologi, urutan attack, dan trade-off yang harus didiskusikan dengan engineering team.
Konteks workload
- App: marketplace e-commerce + logistics fulfillment.
- MAU: ~6 juta, ~480k DAU.
- Tim engineering: 32 engineer (8 squad).
- Stack:
- EKS Kubernetes (sebagian besar workload)
- Beberapa EC2 standalone (legacy)
- RDS Postgres + Aurora
- DynamoDB (catalog, session)
- S3 (product images, logs, backup)
- CloudFront CDN
- SES + SNS untuk notification
- Regions: primary ap-southeast-3 Jakarta, secondary ap-southeast-1 Singapore (DR).
Baseline bill breakdown (Rp 100 juta = $6.300):
| Service | Cost USD | % |
|---|---|---|
| EC2 (compute) | $2.380 | 38% |
| RDS Aurora | $720 | 11% |
| EBS volume | $380 | 6% |
| Data transfer | $640 | 10% |
| S3 + Glacier | $310 | 5% |
| DynamoDB | $580 | 9% |
| EKS control plane | $216 | 3% |
| CloudWatch | $290 | 5% |
| NAT Gateway | $420 | 7% |
| CloudFront | $180 | 3% |
| Lainnya | $184 | 3% |
Strategi: urut attack by ROI
5 phase, urut by ROI tertinggi:
- Reserved Instance + Savings Plan untuk baseline compute (week 1-2)
- S3 lifecycle policy + Intelligent Tiering (week 3-4)
- Data transfer audit + VPC endpoint (week 5-8)
- Spot instance migration untuk batch workload (week 9-14)
- CloudWatch log optimization + retention (week 15-18)
Plus continuous: right-sizing per workload (ongoing).
Phase 1: RI + Savings Plan (week 1-2)
EC2 baseline usage analysis: 18 bulan history Cost Explorer + CloudWatch.
Steady-state vCPU continuous: ~84 vCPU (rata-rata, dengan variance + 12% standar deviasi). RDS baseline: 6 db.r6g.large continuous. DynamoDB steady throughput: 2.400 RCU + 1.800 WCU sustained.
Decision:
- Compute Savings Plan 1-year, no upfront: cover 70 vCPU baseline (leave 14 vCPU + bursty untuk On-Demand). Rate: $1.62/hour committed.
- RDS RI 1-year, no upfront: 6 db.r6g.large covered. Saving rate ~31%.
- DynamoDB Reserved Capacity 1-year: 2.000 RCU + 1.500 WCU covered. Saving rate ~50%.
Calc saving estimated:
- Compute SP: ~32% saving on $2.380 baseline → save $760/month.
- RDS RI: ~31% on $720 → save $220/month.
- DDB RC: ~50% on covered portion → save $180/month.
Total estimated: ~$1.160/month.
After 1 month observation: ~$1.080/month actual (slightly less because workload not 100% match commitment shape). Acceptable.
Phase 2: S3 lifecycle + Intelligent Tiering (week 3-4)
Audit S3 bucket: 8 bucket, total ~84 TB.
| Bucket | Size | Access pattern | Storage class |
|---|---|---|---|
| product-images | 24 TB | Mixed (hot for new, cold for old) | Standard |
| order-attachments | 18 TB | Cold after 90 days | Standard |
| db-backup | 22 TB | Archive after 30 days | Standard-IA |
| log-archive | 14 TB | Compliance retention 7 years | Standard |
| ml-training-data | 4 TB | Cold most of the time | Standard |
| Lainnya | 2 TB | Various | Standard |
Action:
product-images → Intelligent Tiering
aws s3api put-bucket-intelligent-tiering-configuration \
--bucket prod-product-images \
--id "ImagesTiering" \
--intelligent-tiering-configuration '{
"Id": "ImagesTiering",
"Status": "Enabled",
"Tierings": [
{ "Days": 90, "AccessTier": "ARCHIVE_ACCESS" },
{ "Days": 180, "AccessTier": "DEEP_ARCHIVE_ACCESS" }
]
}'
Cost product-images: $552 → $310/month. Saving $240.
order-attachments → Lifecycle to Glacier
{
"Rules": [{
"Id": "GlacierTransition",
"Status": "Enabled",
"Filter": {},
"Transitions": [
{ "Days": 90, "StorageClass": "GLACIER_IR" },
{ "Days": 365, "StorageClass": "DEEP_ARCHIVE" }
]
}]
}
Glacier IR cost ~$0.004/GB vs Standard $0.023/GB.
Saving order-attachments: $414 → $98/month. Saving $316.
log-archive → already optimized, audit retention
7-year compliance retention mandatory (Bank Indonesia + tax). Tapi audit show 4 TB log archive yang tidak ada compliance reason (internal debug log dari 2019).
Delete 4 TB. Saving $92/month.
db-backup → optimize backup count
Aurora automated backup retention 35 days (max), tapi manual snapshot accumulate. Audit: 287 manual snapshot (~28 TB).
Action: cleanup manual snapshot, keep 30 latest + 1 per month for 2 years (compliance).
Saving: $180/month.
Phase 2 total saving: ~$828/month.
Phase 3: Data transfer audit (week 5-8)
Data transfer $640/month: yang paling tidak transparan di bill AWS.
Investigation via VPC Flow Logs + Cost Explorer:
| Source | Destination | Volume/month | Cost |
|---|---|---|---|
| EKS pod cross-AZ | EKS pod cross-AZ | 8.2 TB | $164 ($0.02/GB × 2 sides) |
| EKS → RDS cross-AZ | (Within VPC) | 4.8 TB | $96 |
| Pod → S3 via NAT | S3 | 3.2 TB | $144 (NAT $0.045/GB + transfer) |
| Pod → ECR pull | ECR | 1.8 TB | $40 |
| CloudWatch logs | CloudWatch | (covered separately) | - |
| Internet egress | Internet | 4.2 TB | $378 |
| Internet ingress | (free) | - | $0 |
Action 1: EKS pod cross-AZ
Penyebab: pod scheduling tidak rack-aware. Service-to-service call random AZ.
Fix: enable topology-aware routing di Kubernetes Service:
apiVersion: v1
kind: Service
metadata:
name: order-service
annotations:
service.kubernetes.io/topology-aware-hints: "auto"
spec:
selector:
app: order-service
ports:
- port: 80
Plus pod affinity rule untuk co-locate frequently-talking pairs.
Saving cross-AZ: ~$120/month.
Action 2: VPC endpoint untuk S3
Pod → S3 via NAT Gateway. Setup S3 Gateway Endpoint (gratis, no per-GB fee):
aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxx \
--service-name com.amazonaws.ap-southeast-3.s3 \
--route-table-ids rtb-xxx rtb-yyy rtb-zzz
Saving S3 traffic via NAT: $144/month.
Action 3: VPC endpoint untuk ECR
Setup ECR Interface Endpoint + S3 Gateway Endpoint untuk ECR’s underlying S3 storage. Image pull via private link, no NAT egress.
Saving ECR: $34/month.
Action 4: CloudFront untuk internet egress
4.2 TB internet egress termasuk API response. CloudFront caching reduce origin egress.
Setup CloudFront in front of public API + static assets. Cache hit ratio target 75%.
After 6 weeks tuning: cache hit ratio 71% achieved. Origin egress drop ke 1.4 TB/month.
Tapi CloudFront cost sendiri: $180 → $260 (more traffic). Net saving:
- Egress saving: 2.8 TB × $0.09 = $252
- CF additional: $80
- Net: $172/month saving
Phase 3 total saving: ~$470/month.
Phase 4: Spot untuk batch (week 9-14)
Workload yang cocok spot:
- ML training (~$280/month) — interrupt-tolerant
- Batch report generation (~$140/month) — retry-able
- Image processing pipeline (~$180/month) — async, queue-based
Migration ke EKS NodePool spot dengan Karpenter (lihat juga Kubernetes cost cut Jakarta).
Spot saving rate ~62% di ap-southeast-3 Jakarta untuk family m6i/c6i.
Saving: ~$370/month.
Phase 5: CloudWatch optimization (week 15-18)
CloudWatch $290/month. Audit log group:
| Log group | Volume/day | Retention | Cost/month |
|---|---|---|---|
| /aws/eks/cluster/application | 22 GB | never expire | $185 |
| /aws/lambda/* | 4 GB | 30 days | $32 |
| /aws/rds/postgresql | 3 GB | 90 days | $28 |
| Lainnya | 8 GB | mixed | $45 |
Application log paling besar. Set retention 14 days untuk debug log, 90 days untuk audit log (separated via log group).
Saving: $148/month.
Plus: ship critical log ke S3 via Kinesis Firehose untuk long-term storage cheap ($0.023/GB vs CloudWatch $0.50/GB ingestion + storage).
Hasil setelah 5 bulan
| Category | Sebelum | Sesudah | Delta |
|---|---|---|---|
| EC2 compute | $2.380 | $1.420 (SP + Spot + right-sizing) | -40% |
| RDS Aurora | $720 | $498 (RI) | -31% |
| EBS | $380 | $340 (gp3 migration) | -11% |
| Data transfer | $640 | $284 | -56% |
| S3 + Glacier | $310 | $148 | -52% |
| DynamoDB | $580 | $390 (RC + autoscaling) | -33% |
| CloudWatch | $290 | $142 | -51% |
| NAT Gateway | $420 | $180 (VPC endpoint) | -57% |
| EKS, CF, others | $580 | $598 (CF naik) | +3% |
| Total | $6.300 | $4.000 | -37% |
Total saving: ~$2.300/month = Rp 36-38 juta/bulan (kurs 16.300).
Yang break (atau hampir)
1. Savings Plan over-commit
Initial commitment 80 vCPU. Bulan ke-2, ada incident, scale down sementara → ~62 vCPU usage. Savings Plan unused = bayar tetap.
Fix: commitment moderate (70 vCPU, bukan 80) supaya ada buffer. Plus monthly review utilization.
2. S3 lifecycle transition cost
Glacier transition cost $0.05 per 1000 object. order-attachments punya 18 juta object. Transition cost initial: $900 one-time.
Tidak break, tapi unexpected. Worth karena ongoing saving $316/month.
3. CloudFront cache hit ratio rendah awalnya
First 2 weeks setelah CF setup: cache hit ratio cuma 38% karena cache key configuration default (include Authorization header → no caching for authenticated).
Fix: tune cache key per endpoint. Public asset → cache-all. API GET → cache by query string. API POST/PUT → no cache (default).
After tuning: hit ratio 71%.
4. Spot eviction storm hari ke-31
ML training batch saat training: 8 dari 12 spot node evicted dalam 4 menit. Training restart from checkpoint. Loss: 2 jam compute.
Fix:
- Checkpoint training setiap 30 menit (sebelumnya 2 jam).
- Diversifikasi instance family + AZ.
- Hybrid: 30% on-demand floor untuk training.
After fix: no production impact dari spot eviction.
5. VPC endpoint policy too permissive
Initial S3 Gateway Endpoint policy * allow all. Compliance team flag.
Fix: scope-down policy:
{
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": [
"arn:aws:s3:::company-prod-*/*"
]
}]
}
Yang tidak saya optimize (sengaja)
-
Aurora I/O optimization: Aurora I/O-Optimized variant saving 10-15% untuk write-heavy. Tapi commitment 1-year, kami belum confidence workload pattern stable.
-
ARM Graviton migration: m6i → m7g bisa save 20-30%, tapi butuh rebuild image untuk ARM compatibility. Engineering effort estimated 4 minggu, ROI 8 bulan. Slated untuk kuartal berikutnya.
-
Serverless migration: beberapa workload kandidat Lambda (image processing, webhook), tapi observability + debugging overhead lebih besar. Delay sampai team ready.
-
Multi-region active-active: cost-wise tidak menguntungkan untuk app kami sekarang. DR cukup.
Verdict
AWS cost optimization 35-45% achievable dalam 5-6 bulan tanpa re-architecture. Yang dibutuhkan: disiplin observability (Cost Explorer, VPC Flow Logs), prioritized attack plan (high-ROI first), dan kemauan engineering team handle perubahan (spot eviction, lifecycle policy edge case).
Lebih dari 45% saving butuh re-architecture investment. ROI lebih lambat tapi sustainable.
Bukan magic. Saya track hidden cost di NAT Gateway 4 minggu sebelum sadar itu nomor 3 cost driver. Cost optimization itu detective work, bukan tooling-driven. Lihat juga Kubernetes cost cut 30% untuk konteks K8s-specific optimization yang complementary.
Ditulis oleh Reza Pradipta