In 2024, our cloud bills at Commsult Indonesia were growing faster than our revenue from the projects running on that infrastructure. A single GCP project for a client ERP integration was costing Rp 4.2 million per month — more than double what we had budgeted. After a systematic review, I brought it down to Rp 2.4 million, a 43% reduction, without any performance degradation. The strategies were not exotic — they were basic hygiene that nobody had time to apply when the projects were in rapid development. This guide covers exactly what I did and in what order.
The first step is not optimization — it's measurement. Enable billing export to BigQuery in every GCP project and set up a dashboard in Looker Studio (free) that shows daily spend by service, resource, and label. Without this visibility, optimization is guesswork. On DigitalOcean, the billing overview is simpler but set up spending alerts via the notification settings. The goal of this step is to find the top 3 cost drivers — in our case, Cloud SQL (40%), Compute Engine (35%), and Cloud Storage (15%) accounted for 90% of the bill. Fix those three before touching anything else.
Apply labels to every GCP resource: project, environment, team, and service. Without labels, your BigQuery billing export shows you costs by service but not by which team or feature is driving them. With labels, you can run queries like 'show me all costs for resources labeled service=invoice-processor in the last 30 days.' This granularity is essential for chargeback to clients and for identifying which internal services are cost outliers. Organizations implementing proper tagging report 25-40% cost reduction simply from the visibility it enables — teams change behavior when they can see what they're spending.
In development, we provision VMs with generous specs to avoid performance issues during testing. Those specs often persist unchanged into production, even when the actual workload is light. GCP's Active Assist provides rightsizing recommendations in the Compute Engine console — check it monthly. In my case, three e2-standard-4 instances (4 vCPU, 16GB RAM) running at average 15% CPU utilization were candidates to downsize to e2-standard-2. The switch saved $45/month with zero user-facing impact. Cloud SQL is even more impactful — db-custom-4-16384 running at 20% CPU and 30% RAM is a $80/month savings if you downsize to db-custom-2-8192.
From my experience: the highest-leverage optimization on GCP is Committed Use Discounts (CUDs) for resources you know you'll run for at least 12 months. A 1-year CUD on a Cloud SQL db-custom-4-16384 instance saves approximately 37% compared to on-demand pricing — that's often $60-100/month saved on a single database instance. Purchase CUDs only after rightsizing, because a CUD locks you into a specific resource type for 12 months. Rightsize first, then commit.
For batch processing and non-critical background jobs, Spot VMs (preemptible on GCP) offer 60-91% discounts compared to on-demand prices. The trade-off is that Spot VMs can be terminated with 30 seconds notice. For fault-tolerant workloads — thumbnail generators, batch report jobs, data export tasks — this is an excellent trade. Design these workloads to checkpoint progress and restart gracefully. At Commsult Indonesia, we run our PDF report generation and data export jobs on Spot VMs, saving $35/month compared to running them on on-demand instances.
# List GCP rightsizing recommendations
gcloud recommender recommendations list --recommender=google.compute.instance.MachineTypeRecommender --location=asia-southeast1-b --project=my-project --format="table(name,description,stateInfo.state)"
# Check Committed Use Discount recommendations
gcloud recommender recommendations list --recommender=google.compute.commitmentRecommender --location=asia-southeast1 --project=my-project
# Schedule non-production instance shutdown (Cloud Scheduler + gcloud)
gcloud scheduler jobs create http stop-dev-instances --schedule="0 20 * * 1-5" --time-zone="Asia/Jakarta" --uri="https://compute.googleapis.com/compute/v1/projects/my-project/zones/asia-southeast1-b/instances/dev-server/stop" --oauth-service-account-email=scheduler-sa@my-project.iam.gserviceaccount.comDevelopment and staging environments don't need to run 24/7. A Cloud Scheduler job that starts GCP instances at 8 AM Jakarta time and stops them at 8 PM saves 50% of compute costs for those environments immediately. For Cloud SQL in non-production environments, enable the automatic storage increase feature but downsize the machine type significantly — dev/staging databases rarely need more than db-custom-2-4096. Implement instance scheduling with a simple Cloud Function triggered by Cloud Scheduler for start/stop operations.
┌──────────────────────────────────────────────────────┐
│ GCS Storage Class Lifecycle Policy │
├──────────────────────────────────────────────────────┤
│ Day 0 → Standard ($0.020/GB/month) │
│ Day 30+ → Nearline ($0.010/GB/month) ─┐ │
│ Day 90+ → Coldline ($0.004/GB/month) ─┤ Auto │
│ Day 365+ → Archive ($0.0012/GB/month) ─┘ │
├──────────────────────────────────────────────────────┤
│ 500GB log bucket: $10/mo → under $2/mo with ILM │
└──────────────────────────────────────────────────────┘GCP Cloud Storage has four storage classes: Standard, Nearline, Coldline, and Archive. Standard costs $0.02/GB/month; Archive costs $0.0012/GB/month — 16x cheaper. But Archive has a 365-day minimum storage duration and $0.05/GB retrieval cost. Implement lifecycle policies that automatically transition objects: move log files to Nearline after 30 days, Coldline after 90 days, and Archive after 365 days. For a bucket storing 500GB of logs, this lifecycle policy reduces monthly storage costs from $10 to under $2. The GCP console's lifecycle rule editor makes this a 5-minute task.
When I was optimizing our Cloud SQL costs, I noticed that automated backup retention was set to 30 days on all instances including dev. The dev instance backup costs added $8/month. I was tempted to reduce dev backup retention to 1 day to save costs — but our dev environment sometimes contains real data snapshots from production (for debugging), which means losing the ability to recover a dev database could cause real data loss. The lesson: optimize compute and storage tiers aggressively, but be conservative with backup and recovery configuration. The cost of a data recovery incident far exceeds the savings from minimal backup retention.
GCP charges for data leaving a region — $0.085/GB for Asia region egress to internet. If your application serves 50GB/day of images or file downloads, that's $127/month in egress alone. Solutions: use a CDN (Cloud CDN or Cloudflare in front of GCP) to cache static assets at the edge, reducing origin egress by 60-80%. Place Cloud Storage buckets and application servers in the same region to avoid inter-region transfer costs. Use Private Google Access for services communicating within GCP to avoid public IP routing charges.
The 43% cost reduction I achieved was not a one-time fix — it's an ongoing practice. I now review cloud bills weekly, set budget alerts at 80% of expected monthly spend, and have a standing item in our monthly team meeting for cloud cost review. The discipline of FinOps — making cloud cost a shared team responsibility rather than something only DevOps thinks about — is what sustains savings over time. For Indonesian companies working with clients who pay in IDR, predictable and controlled cloud costs are essential for project profitability, especially when GCP prices are in USD and the IDR/USD rate fluctuates.
Sources & Further Reading