---
title: "Next.js on Google Cloud Run: Production Caching, Secrets, and Zero Cold Starts"
date: "2026-03-25"
slug: "nextjs-on-cloud-run-production-guide"
author: "Dany Paredes"
canonical: "https://danywalls.com/nextjs-on-cloud-run-production-guide"
description: "A production guide to running Next.js on Google Cloud Run: configure Cloud CDN asset caching, mount Secret Manager env variables, reduce cold starts, and automate Cloud Build."
---


In my previous guide, [Moving from Vercel Next.js to Google Cloud Run](/migrating-nextjs-from-vercel-to-gcp), we walked through setting up standalone Docker builds and deploying to Cloud Run to achieve predictable $0 hosting.

Once your Next.js application is running in a container, the next step is making it truly **production-ready**:
1. How do you serve `_next/static` assets at edge speed without hammering your container?
2. How do you manage API keys and database credentials securely?
3. How do you eliminate cold starts when traffic spikes?
4. How do you automate deployment pipelines with Google Cloud Build?

Here is the architectural blueprint for running high-performance Next.js on Google Cloud Run.

---

## 1. Edge Caching & Cloud CDN for Static Assets ⚡

When you run Next.js on Vercel, static assets in `_next/static` and `public/` are served automatically from edge points of presence. On Cloud Run, every uncached request spins up a container CPU cycle.

To prevent container load and ensure sub-50ms asset delivery, configure **Cache-Control** headers in `next.config.ts`:

```typescript
// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  output: "standalone",
  async headers() {
    return [
      {
        // Cache immutable static bundles for 1 year at the edge
        source: "/_next/static/:path*",
        headers: [
          {
            key: "Cache-Control",
            value: "public, max-age=31536000, immutable",
          },
        ],
      },
      {
        // Cache public images and icons for 24 hours
        source: "/images/:path*",
        headers: [
          {
            key: "Cache-Control",
            value: "public, max-age=86400, stale-while-revalidate=43200",
          },
        ],
      },
    ];
  },
};

export default nextConfig;
```

When placed behind Cloudflare or a Google Cloud Load Balancer with Cloud CDN enabled, static assets are cached at the edge, reducing container requests by over **85%**.

---

## 2. Managing Secrets with Google Secret Manager 🔐

Never bake `.env` files or API secrets into Docker images. Instead, store them in **Google Secret Manager** and mount them into your Cloud Run service at startup.

### Step 1: Create the Secret in GCP

```bash
echo -n "sk_live_my_super_secret_api_key" | gcloud secrets create STRIPE_API_KEY \
  --data-file=- \
  --replication-policy="automatic"
```

### Step 2: Grant Permissions to the Cloud Run Service Account

```bash
PROJECT_ID=$(gcloud config get-value project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")

gcloud secrets add-iam-policy-binding STRIPE_API_KEY \
  --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"
```

### Step 3: Mount Secrets in the Deployment Command

```bash
gcloud run deploy nextjs-blog \
  --image gcr.io/${PROJECT_ID}/nextjs-blog:latest \
  --region us-central1 \
  --set-secrets="STRIPE_SECRET_KEY=STRIPE_API_KEY:latest"
```

In your Next.js code (`process.env.STRIPE_SECRET_KEY`), the value is accessible synchronously as a standard environment variable.

---

## 3. Eliminating Cold Starts 🚀

Cloud Run scales down to zero instances when idle, saving you money. However, the first request after an idle period experiences a cold start.

Here is how to reduce cold start latency from 4 seconds down to under 300ms:

| Technique | Command / Setting | Impact |
|---|---|---|
| **Standalone Output** | `output: 'standalone'` in Next.js | Container drops from 2.1GB to 120MB |
| **Startup CPU Boost** | `--cpu-boost` flag | Allocates 200% CPU during container boot |
| **Minimum Instances** | `--min-instances=1` | Keeps 1 container warm at all times (optional) |
| **Concurrency Tuning** | `--concurrency=80` | Handles up to 80 requests simultaneously per container |

Deploy with startup CPU boost enabled:

```bash
gcloud run deploy nextjs-blog \
  --image gcr.io/${PROJECT_ID}/nextjs-blog:latest \
  --region us-central1 \
  --cpu-boost \
  --concurrency=80 \
  --memory=512Mi \
  --cpu=1
```

---

## 4. Automated CI/CD with Cloud Build 🛠️

Instead of deploying manually from your terminal, set up a `cloudbuild.yaml` file in your repository:

```yaml
# cloudbuild.yaml
steps:
  # 1. Build Docker image with Kaniko cache
  - name: 'gcr.io/kaniko-project/executor:latest'
    args:
      - '--destination=gcr.io/$PROJECT_ID/nextjs-blog:$COMMIT_SHA'
      - '--destination=gcr.io/$PROJECT_ID/nextjs-blog:latest'
      - '--cache=true'
      - '--cache-ttl=24h'

  # 2. Deploy container to Google Cloud Run
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args:
      - 'run'
      - 'deploy'
      - 'nextjs-blog'
      - '--image=gcr.io/$PROJECT_ID/nextjs-blog:$COMMIT_SHA'
      - '--region=us-central1'
      - '--platform=managed'
      - '--allow-unauthenticated'
      - '--cpu-boost'

images:
  - 'gcr.io/$PROJECT_ID/nextjs-blog:$COMMIT_SHA'
  - 'gcr.io/$PROJECT_ID/nextjs-blog:latest'
```

Connect your GitHub repository in the Google Cloud Console under **Cloud Build > Triggers**. Every push to `main` automatically builds, tests, and deploys your Next.js application in under 90 seconds.

---

## Conclusion & Architecture Summary 🎯

Running Next.js on Google Cloud Run gives you enterprise-grade infrastructure without runaway bills:
- **Cloud CDN / Cloudflare Cache-Control** protects your containers and speeds up static assets.
- **Secret Manager** keeps tokens and sensitive credentials secure.
- **Startup CPU Boost** eliminates cold starts.
- **Cloud Build** automates production deployment with zero manual steps.

Ready to migrate? Check out the initial guide: [Moving from Vercel Next.js to Google Cloud Run: A Cost and Architecture Guide](/migrating-nextjs-from-vercel-to-gcp).

_Photo by [Robson Hatsukami Morgan](https://unsplash.com/@robsonhmorgan?utm_source=unsplashx&utm_medium=referral) on [Unsplash](https://unsplash.com/?utm_source=unsplashx&utm_medium=referral)_

