Oct 30, 20265 min read

Cloud Run vs GKE: Which Google Cloud Service Should Run Your Backend

How Cloud Run and Google Kubernetes Engine differ on scaling, billing, networking, operations and portability, for a backend with a few services and a database.

On Google Cloud, a containerized backend usually runs on Cloud Run or on Google Kubernetes Engine. Cloud Run is the shorter path: push a container, get an HTTPS endpoint that scales with traffic. GKE gives you the Kubernetes API and everything that comes with it, which matters once you need sidecars, custom networking or workloads that do not fit the request model.

A common question is when a backend outgrows Cloud Run. This guide compares the two on scaling, billing, networking and operations, and shows how Encore deploys the same services to either one with the same code on both.

Cloud Run vs GKE at a glance

EncoreCloud RunGKE
What you operateApplication codeServices and their settingsA cluster, its workloads and upgrades
Scale to zeroOn Cloud Run environmentsYesNo for the cluster, workloads can scale down
Base costCloud resources in your accountNone when idle$0.10 per cluster per hour, plus compute
NetworkingPrivate Cloud SQL and service accounts set upDirect VPC egress or connectorsFull VPC-native networking
Kubernetes APIGenerated for you on GKENoYes
Database and queuesCloud SQL and Pub/Sub from codeSet up separatelySet up separately

Each option is covered below, starting with Encore.

Running one codebase on Cloud Run or GKE with Encore

Encore combines an open source infrastructure SDK for TypeScript and Go with a platform that provisions and deploys into your own AWS or GCP account. In a GCP environment you choose the compute platform: Cloud Run, or GKE in Autopilot or Standard mode. Databases become Cloud SQL for PostgreSQL, Pub/Sub topics become Google Cloud Pub/Sub with dead-letter topics, secrets live in Secret Manager, and each service gets its own service account.

Application code passes through Encore and infrastructure guardrails to resources provisioned in your own AWS or GCP account.
Encore provisions the infrastructure your application needs in your own AWS or GCP account.

The service code is the same on both platforms:

// inventory/inventory.go package inventory import ( "context" "encore.dev/storage/sqldb" ) // Cloud SQL for PostgreSQL on GCP, a local Postgres under encore run. var db = sqldb.NewDatabase("inventory", sqldb.DatabaseConfig{ Migrations: "./migrations", }) type Stock struct { SKU string `json:"sku"` Quantity int `json:"quantity"` } //encore:api public method=GET path=/stock/:sku func Get(ctx context.Context, sku string) (*Stock, error) { s := &Stock{SKU: sku} err := db.QueryRow(ctx, `SELECT quantity FROM stock WHERE sku = $1`, sku, ).Scan(&s.Quantity) if err != nil { return nil, err } return s, nil }

The migration in inventory/migrations creates the stock table the queries use:

-- inventory/migrations/1_create_stock.up.sql CREATE TABLE stock ( sku TEXT PRIMARY KEY, quantity INTEGER NOT NULL );
Get started
brew install encoredev/tap/encore &&
encore app create
Copy

Run in your terminal to get started locally.

On Cloud Run, each service is deployed with health checks and zero-downtime rollouts behind a load balancer. On GKE, each service becomes a Kubernetes Deployment with its own service account, plus the Service and Ingress resources that connect it to Google Cloud Load Balancing with managed TLS certificates. You do not write the manifests in either case, and encore run starts Postgres locally so the migration and the endpoint can be tested before anything is deployed.

That makes the platform an environment decision. A team can run staging on Cloud Run to keep idle costs low and production on GKE Autopilot, and an agent changing the inventory service never needs to know which one it is targeting.

Cloud Run: services that scale with requests

Cloud Run runs a container image as a service with an HTTPS URL. Instances are added as requests arrive, each one can handle many concurrent requests, and a service with no traffic can scale to zero. Billing is based on the CPU and memory your instances use, per Cloud Run pricing, so a quiet internal API costs very little.

At the edges, Cloud Run requests have a configurable timeout with a maximum of 60 minutes, background work outside a request needs CPU to stay allocated or a separate job, and reaching Cloud SQL or Memorystore on private IPs needs VPC egress configured on every service. Cloud SQL, Pub/Sub subscriptions, Secret Manager entries and the IAM bindings between them are all separate pieces you create and keep in sync.

GKE: managed Kubernetes

GKE gives you a Kubernetes cluster whose control plane Google runs. In Autopilot mode Google also manages nodes and bills per Pod resource request; in Standard mode you manage node pools and pay for the underlying Compute Engine VMs. Both carry the cluster management fee of $0.10 per cluster per hour, with a free tier credit that covers one Autopilot or zonal cluster per billing account.

What you get is the whole Kubernetes ecosystem: Helm charts, operators, service meshes, long-running workers and fine-grained network policies. What you take on is the work around it: manifests or charts for every service, Workload Identity bindings, ingress configuration, version upgrades and the CI pipeline that applies all of it.

Good to know

The choice is rarely permanent, but moving between the two by hand is a migration. Cloud Run service YAML is Knative-style and does not map one to one to Deployments and Ingress, and the IAM, networking and secret wiring has to be redone.

How to choose

Pick Encore when you want your backend on Google Cloud in your own project with Cloud SQL, Pub/Sub, secrets and service accounts created from the code, and the freedom to run Cloud Run in one environment and GKE in another.

Pick Cloud Run for HTTP services with uneven traffic where scale to zero and minimal operations matter most. Pick GKE when you need Kubernetes itself: existing Helm charts, operators, a service mesh, or a platform team that already runs clusters.

Frequently asked questions

What is the difference between Cloud Run and GKE?

Cloud Run runs containers as managed services that scale with requests, including down to zero, with no cluster to operate. GKE is managed Kubernetes: you get the full Kubernetes API for deployments, networking and custom controllers, and you manage the cluster configuration, either with Autopilot handling the nodes or with Standard node pools you size yourself.

Is Cloud Run cheaper than GKE?

For low or uneven traffic, usually yes, because Cloud Run can scale to zero and has no cluster fee. GKE charges a cluster management fee of $0.10 per cluster per hour (the free tier covers one Autopilot or zonal cluster per billing account) plus compute, which becomes competitive when many services run at steady utilization.

Can I move from Cloud Run to GKE later without rewriting my backend?

With Encore, the compute platform is chosen when you create a GCP environment, and the same TypeScript or Go code deploys to Cloud Run or GKE, so moving means creating a GKE environment and deploying to it, with Cloud SQL, Pub/Sub, Secret Manager and a service account per service created for you in either case.

Deploy to your cloud on AWS and Google Cloud
without managing infrastructure

Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.

~/orders — claude
Claude Code
Claude Code v2.1.180Opus 5.5~/orders