Choosing a runtime
Google Cloud gives you several places to run code. Most of them are Cloud Run underneath: containers that Google starts, scales and stops for you. They differ in what starts them and how long they live. Every one runs the same kind of Alchemy program, takes the same bindings, and runs as a service account of its own.
The same program on every runtime
Section titled “The same program on every runtime”Whichever you pick, you declare it with an id, its configuration and an Effect. Construction binds what it uses. A runtime that answers HTTP returns fetch, and one that runs to completion returns run:
export default class Reindex extends GCP.Run.Job<Reindex>()( "Reindex", { main: import.meta.url }, Effect.gen(function* () { const db = yield* GCP.Firestore.ReadDatabase(Links); return { run: Effect.gen(function* () { const { documents } = yield* db.list("links"); yield* Effect.log(`reindexing ${documents.length} links`); }).pipe(Effect.orDie), }; }).pipe(Effect.provide(GCP.Firestore.ReadDatabaseHttp)),) {}So moving part of an app from one runtime to another changes its declaration, not its bindings. Choose by how the work behaves:
Cloud Run services: answer HTTP
Section titled “Cloud Run services: answer HTTP”A Cloud Run service runs your fetch handler in containers that start as requests arrive, serve many requests each, and stop when traffic does. An idle service costs nothing. Pub/Sub, Cloud Storage, Cloud Scheduler and Eventarc can all push to it, so it handles events as well as requests.
It’s an easy and cheap place to start, and it fits APIs, websites and event handlers.
Cloud Run jobs: run to completion
Section titled “Cloud Run jobs: run to completion”A job starts, does its work and exits. Nothing runs, or is billed, between executions. Start one from another runtime with the RunJob binding, or on a schedule with Cloud Scheduler.
It fits batch work: reindexing, exports, migrations, nightly reports.
Worker pools: always running, no URL
Section titled “Worker pools: always running, no URL”A worker pool keeps containers running whether or not anyone calls them, and has no URL at all. You pay for them while they run.
It fits workers that pull from Pub/Sub around the clock, or hold a connection open.
Cloud Functions: built by Google
Section titled “Cloud Functions: built by Google”A Cloud Function is a Cloud Run service whose image Google builds from your bundled code, instead of your local Docker. Deploys take a few minutes longer, and need no Docker on the machine running them.
It fits deploying from somewhere Docker isn’t available.
GKE: Kubernetes
Section titled “GKE: Kubernetes”GKE runs a Kubernetes cluster, in Autopilot mode with Google managing the nodes. You deploy Deployments and Jobs from the same Stack, and bindings grant roles to each pod’s identity through Workload Identity.
A cluster takes about ten minutes to create and costs money while it exists. Choose it when you want Kubernetes itself: Helm charts, long-lived pods, or workloads you already run on it.
Mix runtimes in one app
Section titled “Mix runtimes in one app”An app rarely needs just one. A common shape is a service for the API, a topic it publishes to, a worker pool that consumes it, and a job that runs nightly:
Each runtime runs as its own service account, granted only the roles its own bindings ask for.