Cloud & DevOpsAugust 12, 20266 min read

Reducing Cloud Infrastructure Costs by 50% on Google Cloud Platform and Docker

Nguyen Dai Long

Nguyen Dai Long

Backend Lead & Software Engineer

As applications grow, cloud infrastructure bills can spiral out of control if left unmonitored. By auditing idle resources, migrating from over-provisioned virtual machines to serverless container execution on Google Cloud Run, and aggressively optimizing Docker image sizes, our team successfully halved our monthly cloud expenditure from $1,000 to $500 while improving overall uptime and deployment velocity.

1. The Initial Cost Audit: Uncovering the Hidden Spenders

A deep dive into GCP Cost Management revealed three major cost drivers: continuously running Compute Engine instances with less than 15% average CPU utilization, oversized Cloud SQL database tiers, and massive Docker images causing exorbitant Cloud Storage and egress charges during CI/CD builds.

Key Implementation Takeaways:

  • Compute instances running 24/7 at low utilization represent pure financial waste.
  • Review storage class lifecycles: move old build artifacts to Coldline/Archive storage.
  • Set up automated GCP budget alerts with webhooks to Slack to prevent billing surprises.

2. Multi-Stage Docker Builds: Shrinking Images from 1.2GB to 140MB

Our initial Dockerfile bundled full Python build toolchains, GCC compiler packages, and unnecessary development dependencies. By implementing multi-stage builds and switching to python:3.11-slim as our base runtime image, we shrank our container image size by nearly 90%. This reduced container cold start times on Cloud Run from 8.5 seconds down to under 1.4 seconds.

dockerfilendlong.site
# Build stage
FROM python:3.11-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends gcc libpq-dev && rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

# Final minimal runtime stage
FROM python:3.11-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends libpq5 && rm -rf /var/lib/apt/lists/*
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8080
CMD ["gunicorn", "--bind", ":8080", "--workers", "2", "--threads", "8", "config.wsgi:application"]

Key Implementation Takeaways:

  • Always use multi-stage builds to separate compilation tools from production runtimes.
  • Leverage .dockerignore to exclude local virtual environments and git history.
  • Tune gunicorn workers and threads to match the concurrency settings of Cloud Run.

3. Leveraging Cloud Run Concurrency and Auto-Scaling

Unlike traditional Functions-as-a-Service (FaaS) that spin up one container instance per request, Google Cloud Run supports concurrency (up to 250 concurrent requests per container). We tuned our container concurrency to 80 requests per instance, allowing a single 1-vCPU / 512MB RAM container to handle substantial traffic without scaling up prematurely.

Key Implementation Takeaways:

  • Adjust container concurrency based on I/O vs CPU workload characteristics.
  • Set minimum instances to 0 during non-business hours for dev/staging environments.
  • Use Cloud Run request timeouts to automatically terminate hung processes.

Summary & Final Thoughts

Cloud cost optimization is not about sacrificing performance; it is about eliminating waste. By pairing multi-stage Docker builds with Cloud Run's granular per-second billing model, we achieved superior reliability, zero-maintenance scaling, and an immediate 50% cost reduction.

#GCP#Cloud Run#Docker#DevOps#Cost Optimization
Nguyen Dai Long

Written by Nguyen Dai Long

Backend Engineer & Backend Lead with 4+ years of hands-on experience building production systems, RESTful APIs, and cloud infrastructure using Python (Django), Laravel, PostgreSQL, and Google Cloud Platform.