First look at Cloud Run instances
Sometimes you want to run a single container in the cloud without an autoscaler spinning up extra copies or shutting down the instance while you work on it. With standalone Cloud Run instances in public preview, you can start an individual container, connect over SSH, and stop and start it on demand.
Until now,
Cloud Run
offered three ways to run containers on Google Cloud: services (which autoscale based on
incoming HTTP requests), jobs (which run batch tasks to completion), and worker pools
(which run fixed or autoscaled pools of background workers that don't need HTTP
ingress). A
standalone Cloud Run instance
(gcloud beta run instances) gives you one container with its own lifecycle
(create, stop, start, and restart),
an optional run.app HTTPS URL, and SSH enabled by default.
Here's how to use Cloud Run instances across three practical workflows (an on-demand Linux box, a persistent workspace backed by a Cloud Storage bucket, and a singleton web server), followed by a look at regional availability, shared-CPU bursting, and pricing.
Running an on-demand Linux box
To spin up an Ubuntu workstation without exposing an HTTP port, you create a dedicated
service account, launch an instance running sleep infinity with
--no-default-url, and connect using SSH.
First, set your Google Cloud project ID in your shell:
export PROJECT_ID="YOUR_PROJECT_ID"
By default, Cloud Run workloads run as the Compute Engine default service account, which usually has broad permissions across your project (so any process or compromised package inside the container could access or modify unrelated cloud resources). Create a dedicated, least-privilege service account for the instance instead:
gcloud iam service-accounts create dev-box-sa \
--display-name="Cloud Run dev box service account" \
--project=$PROJECT_ID
Created service account [dev-box-sa].
Next, create a dev-box instance in europe-west4 using the
ubuntu:24.04 image:
gcloud beta run instances create dev-box \
--image=ubuntu:24.04 \
--command=sleep \
--args=infinity \
--no-default-url \
--service-account=dev-box-sa@$PROJECT_ID.iam.gserviceaccount.com \
--region=europe-west4 \
--project=$PROJECT_ID
-
--image=ubuntu:24.04pulls the official Ubuntu 24.04 image from Docker Hub. -
--command=sleepand--args=infinitykeep the container's initial process (PID 1) alive indefinitely. -
--no-default-urldisables therun.appHTTPS endpoint since this instance only accepts SSH connections. -
--service-accountassigns the dedicated service accountdev-box-sato the container. -
--region=europe-west4places the instance in the Netherlands. As of October 2026, Cloud Run instances are available in most regions excepteurope-west1,us-central1, andus-east1(see Regional availability, CPU bursting, and pricing below).
Creating the instance imports the container image, provisions a lightweight virtual
machine (microVM) on Cloud Run's second-generation execution environment, and prints the
gcloud beta run instances ssh command to connect:
Creating Cloud Run instance [dev-box] in project [YOUR_PROJECT_ID] region [europe-west4]
Creating instance...
Importing container... Imported container image in 6.58s....done
Provisioning resources... Provisioned imported containers....done
Starting instance...done
Done.
Instance [dev-box] has successfully been created.
See logs with:
gcloud beta run instances logs read dev-box --region europe-west4
Connect to the instance with:
gcloud beta run instances ssh dev-box --region europe-west4 --project YOUR_PROJECT_ID
Unlike Cloud Run services (where you pass --ssh at deploy time to opt in),
Cloud Run instances enable SSH by default. Open a shell inside the instance
dev-box:
gcloud beta run instances ssh dev-box \
--region=europe-west4 \
--project=$PROJECT_ID
Project: YOUR_PROJECT_ID
Region: europe-west4
Instance: dev-box
Revision: dev-box-wtyhh3s5y5
Container: worker
Image: mirror.gcr.io/library/ubuntu@sha256:a2d43bffc46670d7108bb3c0468c67c5557c4c92e83e1e34cbff1322ad1b94dc
root@localhost:/# uname -a
Linux localhost 6.6.137+ #1 SMP PREEMPT_DYNAMIC Thu Oct 15 09:05:57 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
root@localhost:/# exit
Cloud Run prints the instance metadata and drops you into a
root@localhost shell inside the container. In the session above, running
uname -a shows the microVM's Linux kernel (6.6.137+), and
exit closes the SSH connection.
Closing the SSH session leaves the container running in the background. Stop the instance when you're not using it so you aren't billed for idle compute time:
gcloud beta run instances stop dev-box \
--region=europe-west4 \
--project=$PROJECT_ID
Stopping [dev-box]...done.
Stopped instance [dev-box].
Listing your instances now shows dev-box with a stopped icon
(■):
gcloud beta run instances list --project=$PROJECT_ID
INSTANCE REGION CREATED AT CREATED BY
■ dev-box europe-west4 2026-10-22 13:00:21 UTC developer@example.com
When you need the environment again, start it back up:
gcloud beta run instances start dev-box \
--region=europe-west4 \
--project=$PROJECT_ID
Starting [dev-box]...done.
Started instance [dev-box].
Listing your instances again shows dev-box with a running icon
(▶):
gcloud beta run instances list --project=$PROJECT_ID
INSTANCE REGION CREATED AT CREATED BY
▶ dev-box europe-west4 2026-10-22 13:00:21 UTC developer@example.com
Persisting files across restarts with a Cloud Storage bucket
Stopping a Cloud Run instance terminates its microVM. Everything written to the
container's filesystem lives in memory and disappears when you run stop or
restart. To keep project files across sessions, you can
mount a Cloud Storage bucket
as a local directory inside the container.
Mounting a bucket at /workspace
First, create a regional bucket in the same region as your instance
(europe-west4), grant the roles/storage.objectUser IAM role
(permission to read and write objects) on that bucket to the service account
dev-box-sa, and update the instance dev-box to mount the
bucket at the directory /workspace.
Create the Cloud Storage bucket:
gcloud storage buckets create gs://$PROJECT_ID-dev-box-workspace \
--location=europe-west4 \
--uniform-bucket-level-access \
--project=$PROJECT_ID
Creating gs://YOUR_PROJECT_ID-dev-box-workspace/...
-
--location=europe-west4creates the bucket in the same region as the instance to minimize network latency and avoid cross-region data transfer charges. -
--uniform-bucket-level-accessdisables legacy per-object Access Control Lists (ACLs) so access is managed uniformly through IAM policies.
Grant the service account dev-box-sa permission to read and write objects
in the bucket:
gcloud storage buckets add-iam-policy-binding gs://$PROJECT_ID-dev-box-workspace \
--member="serviceAccount:dev-box-sa@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/storage.objectUser" \
--project=$PROJECT_ID
bindings:
- members:
- serviceAccount:dev-box-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com
role: roles/storage.objectUser
Now update the instance dev-box to attach the bucket as a
cloud-storage volume mounted at the directory /workspace:
gcloud beta run instances update dev-box \
--add-volume=name=workspace,type=cloud-storage,bucket=$PROJECT_ID-dev-box-workspace \
--add-volume-mount=volume=workspace,mount-path=/workspace \
--region=europe-west4 \
--project=$PROJECT_ID
-
--add-volumeregisters a volume namedworkspacebacked by the$PROJECT_ID-dev-box-workspaceCloud Storage bucket. -
--add-volume-mountmounts theworkspacevolume into the container filesystem at the directory/workspace.
Updating the instance restarts it with the bucket mounted at the directory
/workspace:
Updating Cloud Run instance [dev-box] in project [YOUR_PROJECT_ID] region [europe-west4]
Updating instance...
Importing container... Imported container image in 1.06s....done
Provisioning resources... Provisioned imported containers....done
Starting instance...done
Done.
Instance [dev-box] has successfully been updated.
To verify what persists across a restart, connect to the instance
dev-box over SSH and write one file to /tmp/session.txt and
another to /workspace/persistent.txt:
gcloud beta run instances ssh dev-box \
--region=europe-west4 \
--project=$PROJECT_ID
Project: YOUR_PROJECT_ID
Region: europe-west4
Instance: dev-box
Revision: dev-box-9k4m2p8x1q
Container: worker
Image: mirror.gcr.io/library/ubuntu@sha256:a2d43bffc46670d7108bb3c0468c67c5557c4c92e83e1e34cbff1322ad1b94dc
root@localhost:/# echo "temp data" > /tmp/session.txt
root@localhost:/# echo "saved across restarts" > /workspace/persistent.txt
root@localhost:/# exit
Now restart the instance dev-box (which stops the current microVM and
starts a new one) and reconnect over SSH:
gcloud beta run instances restart dev-box \
--region=europe-west4 \
--project=$PROJECT_ID
Stopping [dev-box]...done.
Starting [dev-box]...done.
Restarted instance [dev-box].
gcloud beta run instances ssh dev-box \
--region=europe-west4 \
--project=$PROJECT_ID
Project: YOUR_PROJECT_ID
Region: europe-west4
Instance: dev-box
Revision: dev-box-7r2n5v9c4m
Container: worker
Image: mirror.gcr.io/library/ubuntu@sha256:a2d43bffc46670d7108bb3c0468c67c5557c4c92e83e1e34cbff1322ad1b94dc
root@localhost:/# cat /tmp/session.txt
cat: /tmp/session.txt: No such file or directory
root@localhost:/# cat /workspace/persistent.txt
saved across restarts
root@localhost:/# exit
In the session above, notice that the SSH header reports a new revision ID (dev-box-7r2n5v9c4m
instead of dev-box-9k4m2p8x1q) and /tmp/session.txt is gone
because restarting the instance replaced the microVM and its in-memory root filesystem.
Meanwhile, /workspace/persistent.txt remains intact in the mounted Cloud
Storage bucket.
A note on file-based databases like SQLite
One thing to be aware of: some file-based databases, such as SQLite, start returning
database is locked errors or suffer silent corruption when you store their
files directly on a Cloud Storage mount like /workspace in this example.
While the mounted bucket looks like a normal directory inside your container, Cloud Run
attaches it using Cloud Storage FUSE, a user-space object storage adapter rather than a
POSIX block filesystem. Cloud Storage FUSE doesn't support POSIX byte-range file locking
(fcntl or flock) and can't update individual database pages in
place; modifying a small range of bytes re-uploads the entire object when the file
handle closes. To avoid corruption, keep the active SQLite database file on the
container's local in-memory filesystem (such as /tmp), restore it from the
bucket on startup, and back it up to the bucket on shutdown, or use an external
database.
Hosting a singleton web app
Some apps assume they're running as a single stateful process. Deploying them to a standard Cloud Run service can cause subtle bugs if the autoscaler spins up a second replica, or when it shuts down the last remaining instance.
A Cloud Run instance gives that workload a dedicated run.app HTTPS URL
backed by exactly one container, and can run continuously for up to 7 days between
automatic infrastructure restarts.
Create a web-demo instance running Python's built-in HTTP server on port
8080:
gcloud beta run instances create web-demo \
--image=python:3.15-slim \
--command=python3 \
--args=-m,http.server,8080 \
--port=8080 \
--restart-policy=on-failure \
--service-account=dev-box-sa@$PROJECT_ID.iam.gserviceaccount.com \
--region=europe-west4 \
--project=$PROJECT_ID
-
--port=8080tells Cloud Run's ingress proxy which container port receives HTTP requests. Whenever an instance has a default URL enabled, Cloud Run also runs a default TCP startup probe against this port (waiting up to 240 seconds for the container to start listening) before routing HTTP or SSH traffic to the instance. -
--restart-policy=on-failure(the default) restarts the container automatically up to three times if the process exits with a non-zero status code or fails its startup probe. You can also set--restart-policy=alwaysto restart on any exit code, or--restart-policy=neverto leave the instance stopped after a failure.
Because --default-url is enabled unless you pass
--no-default-url, Cloud Run assigns an HTTPS URL and locks it down by
default:
Done.
Instance [web-demo] has successfully been created.
See logs with:
gcloud beta run instances logs read web-demo --region europe-west4
URL: https://web-demo-123456789012.europe-west4.run.app
Proxy locally with:
gcloud beta run instances proxy web-demo --region europe-west4 --project YOUR_PROJECT_ID
To make this URL public, use gcloud beta run instances update web-demo --no-invoker-iam-check --region europe-west4
Testing privately with the local proxy
If you request the run.app URL without credentials right now, Google
Frontend returns HTTP/2 403. To reach the instance privately from your
laptop using your Google Cloud credentials, start the local proxy:
gcloud beta run instances proxy web-demo \
--region=europe-west4 \
--port=8888 \
--project=$PROJECT_ID
Proxying to Cloud Run instance [web-demo] in project [YOUR_PROJECT_ID] region [europe-west4]
http://127.0.0.1:8888 proxies to https://web-demo-123456789012.europe-west4.run.app
Sending a request to http://localhost:8888 attaches your IAM token
automatically and returns the directory listing from the Python container:
curl -i http://localhost:8888
HTTP/1.1 200 OK
Content-Length: 832
Content-Type: text/html; charset=utf-8
Server: Google Frontend
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory listing for /</title>
</head>
Making the instance URL public
When you want to expose the singleton web app to the internet without requiring callers
to present a Google Cloud IAM token, update the instance with --public:
gcloud beta run instances update web-demo \
--public \
--region=europe-west4 \
--project=$PROJECT_ID
Updating Cloud Run instance [web-demo] in project [YOUR_PROJECT_ID] region [europe-west4]
Updating instance...done.
Done.
Instance [web-demo] has successfully been updated.
URL: https://web-demo-123456789012.europe-west4.run.app
Unauthenticated requests to the run.app URL now succeed directly:
curl -i https://web-demo-123456789012.europe-west4.run.app
HTTP/2 200
content-type: text/html; charset=utf-8
server: Google Frontend
content-length: 832
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory listing for /</title>
</head>
Regional availability, CPU bursting, and pricing
Before moving a workload into regular use, it helps to know which regions support Cloud Run instances, how the shared-CPU burst model works, and what an instance costs while running compared to when it's stopped.
Selecting a supported region
As of October 2026, Cloud Run instances are available in almost every Google Cloud
region except the three oldest high-demand locations:
europe-west1 (Belgium), us-central1 (Iowa), and
us-east1
(South Carolina). You can check the latest regional rollout table in the
Cloud Run locations documentation.
If you try to create an instance in an unsupported region such as
europe-west1, gcloud CLI returns a
REGION_CAPACITY_EXHAUSTED precondition error along with the full list of
supported regions in the error metadata:
gcloud beta run instances create dev-box \
--image=ubuntu:24.04 \
--command=sleep \
--args=infinity \
--region=europe-west1 \
--project=$PROJECT_ID
Creating Cloud Run instance [dev-box] in project [YOUR_PROJECT_ID] region [europe-west1]
Creating instance...failed
ERROR: (gcloud.beta.run.instances.create) FAILED_PRECONDITION: Instance capacity in region
europe-west1 is currently exhausted. Please pick a different region.
- '@type': type.googleapis.com/google.rpc.ErrorInfo
domain: run.googleapis.com
metadata:
available_regions:
africa-south1,asia-east1,asia-east2,asia-northeast1,asia-northeast2,asia-northeast3,asia-south1,asia-south2,asia-southeast1,asia-southeast2,asia-southeast3,asia-southeast4,australia-southeast1,australia-southeast2,europe-central2,europe-north1,europe-north2,europe-southwest1,europe-west10,europe-west12,europe-west15,europe-west2,europe-west3,europe-west4,europe-west6,europe-west8,europe-west9,me-central1,me-central2,me-west1,northamerica-northeast1,northamerica-northeast2,northamerica-south1,southamerica-east1,southamerica-west1,us-central2,us-east4,us-east5,us-east7,us-south1,us-west1,us-west2,us-west3,us-west4,us-west8
reason: REGION_CAPACITY_EXHAUSTED
For European workloads, europe-west4 (Netherlands) supports Cloud Run
instances. For US workloads, us-east4 (Northern Virginia) or
us-west1 (Oregon) are good defaults.
Shared CPU bursting and cost estimates
A Cloud Run instance defaults to 2 vCPUs and 2 GiB of memory (--cpu=2 --memory=2Gi), with a minimum of 1 vCPU and 512 MiB of memory (--cpu=1 --memory=512Mi). You can configure an instance with 1, 2, 4,
6, or 8 vCPUs and up to 32Gi of memory.
Cloud Run instances use a shared CPU allocation model:
-
Each instance receives a continuous baseline of 6.25% (
1/16th) of its configured vCPUs. - Whenever CPU usage sits below that 6.25% baseline, the instance accrues unused CPU time into a burst balance budget (up to 500 seconds, or about 8 minutes).
- When the instance uses more than 6.25% CPU, it bursts up to 100% of its configured vCPUs until the burst balance is depleted, after which it throttles back to the 6.25% baseline until the budget replenishes.
Cloud Run bills instances only while they're running. When you stop an instance with
gcloud beta run instances stop, compute billing drops to
$0 while Cloud Run retains your instance configuration, IAM policy, and URL
mapping. Using the
Cloud Run instances pricing rates
for europe-west4, us-east4, and us-west1 ($0.00000027
per vCPU-second and $0.00000193 per GiB-second):
-
Running the instance
dev-boxwith the default 2 vCPUs and 2 GiB of memory for 2 hours a day across 20 workdays a month (144,000 seconds) and stopping it when you don't use it costs about$0.63per month ($0.08for CPU and$0.56for memory). -
Running the instance
web-demo24/7 for a 30-day month (2,592,000 seconds) with the minimum 1 vCPU and 512 MiB of memory (--cpu=1 --memory=512Mi) costs about$3.20per month ($0.70for CPU and$2.50for memory), or about$11.40per month with the default 2 vCPUs and 2 GiB of memory.
Cloud Run pricing is subject to change and these examples might contain mistakes, so check the Cloud Run pricing page and do your own math for your workloads.
Cleaning up
When you no longer need the test instances or their backing resources, delete the two instances, the Cloud Storage bucket, and the service account so no billable resources remain in your project.
First, delete the dev-box instance:
gcloud beta run instances delete dev-box \
--region=europe-west4 \
--project=$PROJECT_ID \
--quiet
Next, delete the web-demo instance:
gcloud beta run instances delete web-demo \
--region=europe-west4 \
--project=$PROJECT_ID \
--quiet
Remove the Cloud Storage bucket and all objects inside it:
gcloud storage rm --recursive gs://$PROJECT_ID-dev-box-workspace \
--project=$PROJECT_ID
Finally, delete the dev-box-sa service account:
gcloud iam service-accounts delete dev-box-sa@$PROJECT_ID.iam.gserviceaccount.com \
--project=$PROJECT_ID \
--quiet
If you spin up a Cloud Run instance for a remote workstation or a stateful singleton app, I'd love to hear what you build with it.