Skip to content
← Back to articlesBackend & Cloud
·7 min read·By Mothilal M

Architecting Scalable FastAPI Microservices on Google Cloud Run

A production-grade architectural guide to building, containerizing with Docker, and scaling resilient Python FastAPI microservices on Google Cloud Run with connection pooling and Redis caching.

PythonFastAPIGCPDockerMicroservicesCloud RunPostgreSQLRedis

1. Why FastAPI for Production Microservices?

When designing microservices that handle thousands of concurrent requests, Python developers often face a trade-off between developer productivity and raw execution speed. FastAPI bridges this gap by combining Starlette's asynchronous I/O foundation with Pydantic's data validation and automatic OpenAPI generation.

At 10xscale.ai, we focus on services that remain maintainable as user demand grows. FastAPI's native async/await syntax enables non-blocking database queries and external HTTP calls, minimizing thread contention under heavy I/O workloads.

2. Database Connection Pooling with Asyncpg & SQLAlchemy

In serverless container environments like GCP Cloud Run, containers can scale horizontally from zero to tens of instances in seconds. If each instance opens too many database connections, you quickly exhaust Cloud SQL connection limits.

The solution is pairing SQLAlchemy 2.0 async engine with asyncpg and an appropriate pool size, complemented by PgBouncer or Cloud SQL Auth Proxy.

core/database.py
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from core.config import settings

engine = create_async_engine(
    settings.DATABASE_URL,
    pool_size=5,
    max_overflow=10,
    pool_timeout=30,
    pool_recycle=1800,
    pool_pre_ping=True,
    echo=False,
)

AsyncSessionLocal = async_sessionmaker(
    bind=engine,
    class_=AsyncSession,
    expire_on_commit=False,
)

3. Lean Multi-Stage Docker Builds

Container startup latency directly determines cold-start duration on Cloud Run. Standard Python images can easily swell to 1GB+, delaying scale-up events.

Using a multi-stage Docker build with python:3.12-slim reduces image size to less than 150MB, stripping out compiler tools and build dependencies from the final production runner.

Dockerfile
FROM python:3.12-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends gcc libpq-dev
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

FROM python:3.12-slim AS runner
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . /app
ENV PATH=/root/.local/bin:$PATH
ENV PYTHONUNBUFFERED=1
EXPOSE 8080

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080", "--workers", "2"]

4. Deployment & Traffic Splitting on Cloud Run

Deploying via Google Cloud SDK allows automated continuous delivery with zero downtime. Canary deployments and instant rollback can be achieved with traffic splitting.

deploy.sh
gcloud run deploy user-service \
  --image gcr.io/$PROJECT_ID/user-service:v2.0 \
  --platform managed \
  --region asia-south1 \
  --memory 512Mi \
  --cpu 1 \
  --min-instances 1 \
  --max-instances 50 \
  --concurrency 80 \
  --allow-unauthenticated

5. High-Speed Caching with Redis

To shield primary database replicas from repetitive query loads, frequently accessed domain objects are cached in Memorystore (Redis) with exponential backoff and cache-aside patterns. This ensures median response times remain below 30ms.

Conclusion

Building production microservices requires balancing code clarity, container optimization, and infrastructure resilience. By combining FastAPI's async foundations with Cloud Run's autoscaling and Redis caching, teams can deliver enterprise-grade performance with minimal operational complexity.

Written by Mothilal M

Mothilal M is a Software Engineer at 10xscale.ai specializing in Python, FastAPI, Google Cloud Platform, and scalable microservices.