karawaci.kode

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):

ServiceCost USD%
EC2 (compute)$2.38038%
RDS Aurora$72011%
EBS volume$3806%
Data transfer$64010%
S3 + Glacier$3105%
DynamoDB$5809%
EKS control plane$2163%
CloudWatch$2905%
NAT Gateway$4207%
CloudFront$1803%
Lainnya$1843%

Strategi: urut attack by ROI

5 phase, urut by ROI tertinggi:

  1. Reserved Instance + Savings Plan untuk baseline compute (week 1-2)
  2. S3 lifecycle policy + Intelligent Tiering (week 3-4)
  3. Data transfer audit + VPC endpoint (week 5-8)
  4. Spot instance migration untuk batch workload (week 9-14)
  5. 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.

BucketSizeAccess patternStorage class
product-images24 TBMixed (hot for new, cold for old)Standard
order-attachments18 TBCold after 90 daysStandard
db-backup22 TBArchive after 30 daysStandard-IA
log-archive14 TBCompliance retention 7 yearsStandard
ml-training-data4 TBCold most of the timeStandard
Lainnya2 TBVariousStandard

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:

SourceDestinationVolume/monthCost
EKS pod cross-AZEKS pod cross-AZ8.2 TB$164 ($0.02/GB × 2 sides)
EKS → RDS cross-AZ(Within VPC)4.8 TB$96
Pod → S3 via NATS33.2 TB$144 (NAT $0.045/GB + transfer)
Pod → ECR pullECR1.8 TB$40
CloudWatch logsCloudWatch(covered separately)-
Internet egressInternet4.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 groupVolume/dayRetentionCost/month
/aws/eks/cluster/application22 GBnever expire$185
/aws/lambda/*4 GB30 days$32
/aws/rds/postgresql3 GB90 days$28
Lainnya8 GBmixed$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

CategorySebelumSesudahDelta
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)

  1. 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.

  2. 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.

  3. Serverless migration: beberapa workload kandidat Lambda (image processing, webhook), tapi observability + debugging overhead lebih besar. Delay sampai team ready.

  4. 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