Cloud Run Scaling, Traffic and Jobs
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. See the section bibliography for the reference material consulted while preparing these pages. |
Commands and behaviour below are current for the gcloud CLI 586.x line, the Google Cloud Client Libraries for Java
(libraries-bom) and the Cloud Run documentation as checked on 2026-09-30; re-verify against gcloud version and the
linked reference pages before relying on them in a pipeline. Dated launch stages quoted here (worker pools GA on
2026-04-14, multi-region services GA on 2026-06-29, Cloud Run instances still in Preview) come from the Cloud Run release
notes.
Cloud Run covers what a service is, how to deploy one (source or image), configuration,
identity and networking, and deploys the Bookshelf catalog-api. This page starts where that one stops: how Cloud Run
decides how many instances run, how you move traffic between revisions safely, how run-to-completion work (the
Bookshelf nightly-report job) and background consumers (a worker pool) fit in, and the newer building blocks
(instances, GPUs, multi-region services). The platform-wide choice between Cloud Run, GKE and Compute Engine is in
Choosing a Compute Service.
Autoscaling
A Cloud Run service scales instances out and in automatically between a minimum and a maximum. Each revision of the service is an immutable snapshot of the container image plus its configuration; instances of a revision are the running containers. Cloud Run uses a metrics-based autoscaler: it compares the average CPU utilisation, and the number of concurrent requests per instance, against targets and adds or removes instances to stay near them.
| Control | Behaviour |
|---|---|
Concurrency ( |
Maximum simultaneous requests one instance accepts. Default 80, maximum 1,000. Set to 1 for code that is not safe to share between requests. A Java service on virtual threads or reactive code usually does well at the default or higher. |
Min instances ( |
Instances kept warm even with no traffic. Default 0 (scale to zero). Removes most cold starts but the idle instances are billed. |
Max instances ( |
Upper bound. Every service has a default limit that depends on the regional quota; set an explicit value to protect a backend such as a Cloud SQL connection limit or a third-party API from a traffic spike. |
CPU and concurrency targets ( |
Utilisation the autoscaler aims for. Defaults 60 percent for each; either one may be disabled but not both. |
Startup CPU boost ( |
Temporarily gives an instance more CPU while it starts and until the first health check passes. Cuts JVM start-up time noticeably for Spring Boot containers. |
Manual scaling ( |
A fixed instance count instead of autoscaling, for predictable workloads. Set |
How it behaves in practice:
-
Requests that arrive while no instance has capacity are queued for a short period (related to the average container start-up time, with a floor of about ten seconds) and answered with HTTP 429 if no instance becomes available.
-
When traffic falls, instances with very low utilisation are shut down first; others are kept idle for a few minutes as spare capacity. Instances can also be stopped at any time, so an application must treat shutdown (
SIGTERM) as normal. -
The autoscaler tolerates a small band around the target before changing the instance count, so the number of instances does not oscillate.
-
Cold start is the time between a request arriving at a scaled-to-zero service and the container being ready. Remedies in order of cost: smaller images and lazy initialisation, startup CPU boost,
--minof 1 or more, and, for Java, native-image or CDS/AOT builds (see Quarkus Reference).
Sizing rule of thumb for Bookshelf: catalog-api is I/O bound (database calls), so it runs at the default concurrency
with --min 1 in production and --max set so that max x pool size stays below the Cloud SQL connection limit;
orders-api is similar; a CPU-heavy variant would lower concurrency or raise the CPU target.
In the Google Cloud console
-
Open the project picker and select the Bookshelf project.
-
Go to Cloud Run and select the
catalog-apiservice (APIs must be enabled: Cloud Run Admin API; Cloud Shell has the CLI preinstalled). -
Choose Edit & deploy new revision.
-
Under Container(s) set Startup CPU boost in the Resources section.
-
Under Revision autoscaling set Minimum number of instances and Maximum number of instances; the Scaling tab of the service edit page sets service-level (all revisions) values and the scaling mode (auto or manual).
-
Under Requests set Maximum concurrent requests per instance.
-
Choose Deploy. The new revision starts receiving traffic as configured by the service’s traffic settings.
With the gcloud CLI
gcloud services enable run.googleapis.com cloudscheduler.googleapis.com artifactregistry.googleapis.com
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
SERVICE=catalog-api
# Per-revision settings: a new revision is created
gcloud run services update $SERVICE --region $REGION \
--concurrency 80 \
--cpu-boost \
--min 1 \
--max 20
# Tune what the autoscaler aims for (service level, inherited by new revisions)
gcloud run services update $SERVICE --region $REGION \
--scaling-cpu-target 0.7 \
--scaling-concurrency-target 0.6
# Fixed instance count (manual scaling) and back to autoscaling
gcloud run services update $SERVICE --region $REGION --scaling 3
gcloud run services update $SERVICE --region $REGION --scaling auto
# Inspect the effective settings
gcloud run services describe $SERVICE --region $REGION \
--format="yaml(spec.template.metadata.annotations, spec.template.spec.containerConcurrency)"
Official docs: About instance autoscaling, Custom scaling controls, Manual scaling, gcloud run services update.
--min and --max set per-revision values on the service template; the service-level scaling controls (a separate
setting applied across revisions) are what --scaling and the target flags configure, and they are inherited by later
revisions unless you change them. Min instances at service level are not allocated to tagged revisions that receive no
traffic, which matters when you use the canary pattern below.
Concurrency, CPU billing and cost
Concurrency interacts with billing mode (see Cloud Run): with request-based billing you pay for CPU and memory only while a request is being processed (plus instance start-up) and per request, so higher concurrency means several overlapping requests share one billed instance-second. With instance-based billing you pay for the whole instance lifetime, which suits background work and GPUs. Idle min instances are billed at a lower idle rate under request-based billing. Current rates, the free tier and regional tiers are on the Cloud Run pricing page (pricing changes; re-check before budgeting).
Revisions
Every deploy that changes the container or its configuration creates a new revision named
SERVICE-NNNNN-xyz. Revisions are immutable; traffic and tags are what move. You can list and inspect them, and
revisions that receive no traffic and are not tagged are retained only up to a quota, after which the oldest are
deleted automatically.
gcloud run revisions list --service $SERVICE --region $REGION
gcloud run revisions describe catalog-api-00007-abc --region $REGION
gcloud run revisions delete catalog-api-00003-xyz --region $REGION
Official docs: Manage revisions, gcloud run revisions.
Pin latest versus a named revision deliberately. A service whose traffic is --to-latest always sends 100 percent
to the newest revision; as soon as you route to a named revision, new deployments no longer take traffic unless you
ask for it (they are served only on their tag URL or after another update-traffic).
Traffic management
Cloud Run splits traffic by percentage between revisions of a service. The pieces are:
--no-traffic-
Deploy a new revision that receives 0 percent of traffic.
--tag NAME-
Attach a tag to the revision, which gives it a dedicated URL of the form
https://NAME---SERVICE-hash-region.a.run.app(the exact host is shown in the console and ingcloud run services describe). Tags let you test a revision with real dependencies before it serves users. gcloud run services update-traffic-
Changes the split:
--to-revisions REV=PERCENT,…,--to-tags TAG=PERCENT,…,--to-latest, and--set-tags,--update-tags,--remove-tags,--clear-tags.
In-flight requests are not dropped when the split changes; during the transition a request may reach either the old or the new revision. Traffic percentages must add up to 100.
stable] S -->|10 percent| R2[Revision 00008
canary] T[Tag URL canary---catalog-api] -.->|100 percent of tagged requests| R2 R1 --> DB[(Cloud SQL
bookshelf-catalog)] R2 --> DB
Safe deployment: deploy dark, test, then shift
The pattern behind gradual rollout, blue-green and canary releases is the same three steps.
-
Deploy without traffic and with a tag. The old revision keeps serving 100 percent.
-
Test the tagged URL (smoke tests, a Bookshelf integration run against the real database, or a manual check).
-
Shift traffic in steps and watch error rate and latency, or flip 100 percent for a blue-green cut-over.
Differences between the strategies are only in how step 3 is done: a canary moves a small percentage and waits; a gradual rollout increases it in stages (for example 5, 25, 50, 100); blue-green moves everything at once but keeps the old revision ready for an instant switch back.
In the Google Cloud console
-
Open Cloud Run, select
catalog-api, choose Edit & deploy new revision. -
In the deploy form, clear Serve this revision immediately so the revision receives no traffic, and set a Revision name suffix if you want a readable name. Choose Deploy.
-
Open the Revisions tab, choose Manage traffic.
-
Assign percentages to the revisions (for example 90 and 10) and save. Repeat with larger percentages as the canary proves healthy.
-
To tag a revision, in the Revisions tab use the revision’s Add tag action; the tag URL is listed in its row.
-
For a rollback, in Manage traffic give 100 percent to the previous revision.
With the gcloud CLI
# 1. Deploy a new revision dark, tagged "canary"
gcloud run deploy $SERVICE --region $REGION \
--image $REGION-docker.pkg.dev/$PROJECT_ID/bookshelf/catalog-api:v2 \
--no-traffic --tag canary
# 2. Get the tag URL and smoke test it
CANARY_URL=$(gcloud run services describe $SERVICE --region $REGION \
--format="value(status.traffic.filter(tag=canary).url)")
curl -s -H "Authorization: Bearer $(gcloud auth print-identity-token)" "$CANARY_URL/actuator/health"
# 3. Canary 10 percent, then more
gcloud run services update-traffic $SERVICE --region $REGION --to-tags canary=10
gcloud run services update-traffic $SERVICE --region $REGION --to-tags canary=50
# Promote: everything to the newest revision, and drop the tag
gcloud run services update-traffic $SERVICE --region $REGION --to-latest
gcloud run services update-traffic $SERVICE --region $REGION --remove-tags canary
# Roll back instantly to a known good revision
gcloud run services update-traffic $SERVICE --region $REGION --to-revisions catalog-api-00007-abc=100
Official docs: Rollbacks, gradual rollouts and traffic migration, Revision tags (see also gcloud run services update-traffic).
If a service ever needs to be managed declaratively, the traffic block is part of the service YAML, and the same split
can be expressed with gcloud run services replace service.yaml or the Terraform google_cloud_run_v2_service resource
(traffic blocks with type, revision, tag and percent; see Infrastructure as Code).
# fragment of a service YAML
spec:
traffic:
- revisionName: catalog-api-00007-abc
percent: 90
- revisionName: catalog-api-00008-def
percent: 10
tag: canary
Official docs: Cloud Run YAML reference.
Managing tags and cost
Tagged revisions that you forget keep their URL alive and, if min instances are set on the revision, may keep
instances running. List tags with gcloud run services describe and remove those you no longer need with
--remove-tags or --clear-tags. Quotas cap the number of revision tags per project and region.
Automating the progression
Cloud Deploy supports Cloud Run targets with canary strategies (percentages per phase, verification jobs and automatic
rollback) driven from a Skaffold configuration; it is the managed way to run the manual steps above across
dev, staging and prod projects. It belongs to the delivery pipeline described in
Developer Tools and DevOps. Official docs:
Deploy to Cloud Run with Cloud Deploy.
Multi-region services
A Cloud Run service lives in one region. A multi-region service deploys the same service to several regions with one command and puts a global external Application Load Balancer, a serverless NEG per region, a Google-managed certificate and a global anycast IP address in front of it, so users are routed to the nearest healthy region. It became generally available on 2026-06-29. With Cloud Run service health (a readiness-probe based signal) the load balancer fails traffic over to another region automatically and fails back when the region recovers.
gcloud run deploy $SERVICE \
--image $REGION-docker.pkg.dev/$PROJECT_ID/bookshelf/catalog-api:v2 \
--regions us-central1,europe-west1 \
--min 2 \
--readiness-probe httpGet.path=/actuator/health/readiness
# add or drop a region later
gcloud run deploy $SERVICE --add-regions asia-southeast1
gcloud run deploy $SERVICE --remove-regions asia-southeast1
Official docs: Serve traffic from multiple regions, Automate cross-region failover with service health.
The regional services created this way are managed through the multi-region definition. Design consequences: the database must itself be reachable from both regions (Cloud SQL cross-region replicas or a multi-region data store, see Cloud SQL), min instances are billed in every region, and traffic between the load balancer and the regions is billed as load-balancer egress. Custom domains and Cloud Armor attach to the load balancer, as in Load Balancing and Cloud Armor.
Jobs
A Cloud Run job runs a container to completion instead of serving requests. A job execution consists of one or more
tasks (identical containers) that run in parallel and may retry; the execution succeeds when every task has exited
successfully. Jobs are for batch processing, migrations, report generation and maintenance. In Bookshelf the
nightly-report job imports the catalogue feed and produces a summary report.
| Setting | Meaning |
|---|---|
|
Number of tasks per execution, 1 to 10,000 (default 1). |
|
Maximum tasks running at once. Without it Cloud Run starts as many as the regional capacity allows. |
|
Retries per failed task, 0 to 10 (default 3). A task that exhausts retries fails the execution. |
|
Maximum run time of one attempt. Default 10 minutes, maximum 168 hours (7 days); 1 hour when GPUs are attached. |
|
Environment variables injected into each task: the task’s index from 0, the total number of tasks, and the retry attempt number. Use the index to pick the task’s slice of the data. |
|
Same meaning as for services; jobs also run as a dedicated service account and use Direct VPC egress the same way. |
A job is not a service: it has no URL, does not scale on requests, and tasks must exit (not listen on a port). Jobs
are billed on instance-based billing for the time tasks run. Overrides at execution time (--tasks, --args,
--update-env-vars, --task-timeout) change one run without editing the job.
Task code
package com.example.bookshelf.report;
import java.util.List;
public class NightlyReport {
public static void main(String[] args) {
int index = Integer.parseInt(System.getenv().getOrDefault("CLOUD_RUN_TASK_INDEX", "0"));
int count = Integer.parseInt(System.getenv().getOrDefault("CLOUD_RUN_TASK_COUNT", "1"));
int attempt = Integer.parseInt(System.getenv().getOrDefault("CLOUD_RUN_TASK_ATTEMPT", "0"));
System.out.printf("task %d of %d, attempt %d%n", index, count, attempt);
List<String> shards = ShardCatalog.shards();
for (int i = index; i < shards.size(); i += count) {
process(shards.get(i)); // each task handles every count-th shard
}
// a non-zero exit (or an uncaught exception) marks the attempt failed and triggers a retry
}
private static void process(String shard) { /* read from Cloud SQL, write to the uploads bucket */ }
}
The class uses Application Default Credentials (the job’s attached service account) through the Google Cloud Client Libraries; never mount a downloaded key. Make tasks idempotent because a retry repeats work. Official docs: Create jobs and Execute jobs.
In the Google Cloud console
-
Go to Cloud Run, choose the Jobs tab, then Deploy container (or Create job).
-
Select the image (
REGION-docker.pkg.dev/PROJECT/bookshelf/nightly-report), name the jobnightly-report, pick the region. -
Expand Container, Volumes, Connections, Security: set Task timeout, Number of tasks, Parallelism, Max retries, environment variables and secrets, and the Service account.
-
Choose Create, then Execute to run it, and open the execution’s Tasks and Logs tabs.
-
To run it nightly, open the job, choose Triggers, Add Scheduler Trigger, enter the schedule (unix cron) and time zone, select a service account allowed to invoke the job, and create.
With the gcloud CLI
JOB=nightly-report
gcloud run jobs deploy $JOB --region $REGION \
--image $REGION-docker.pkg.dev/$PROJECT_ID/bookshelf/nightly-report:v1 \
--service-account report-job@$PROJECT_ID.iam.gserviceaccount.com \
--tasks 10 --parallelism 5 \
--max-retries 2 --task-timeout 30m \
--set-secrets DB_PASSWORD=catalog-db-password:latest
# Run it and wait for completion
gcloud run jobs execute $JOB --region $REGION --wait
# Override for one run
gcloud run jobs execute $JOB --region $REGION --tasks 50 --args="--full-import"
# Inspect executions and logs
gcloud run jobs executions list --job $JOB --region $REGION
gcloud logging read "resource.type=cloud_run_job AND resource.labels.job_name=$JOB" --limit 20
Official docs: Create jobs, Execute jobs, gcloud run jobs.
The service account of the job needs roles/secretmanager.secretAccessor on the secret and any data roles, as for a
service. The account that triggers the job needs roles/run.invoker on it (or roles/run.developer for console
use); IAM roles are explained in Identity and Access.
Running jobs on a schedule
Cloud Scheduler calls the Cloud Run Admin API’s jobs/JOB:run endpoint on a cron schedule, authenticating with an
OAuth access token minted for a service account (the endpoint is a Google API, so an OAuth token, not an OIDC ID
token, is required). The same mechanism works for any Google API.
0 2 * * *] -->|POST jobs/nightly-report:run
OAuth token of scheduler SA| API[Cloud Run Admin API] API --> E[Execution] E --> T0[Task 0] E --> T1[Task 1] E --> T2[Task 2] E --> TN[Task 9] T0 --> DB[(Cloud SQL)] T1 --> DB T2 --> DB TN --> B[(Uploads bucket)]
gcloud iam service-accounts create report-scheduler \
--display-name "Bookshelf nightly-report scheduler"
gcloud run jobs add-iam-policy-binding $JOB --region $REGION \
--member "serviceAccount:report-scheduler@$PROJECT_ID.iam.gserviceaccount.com" \
--role roles/run.invoker
gcloud scheduler jobs create http nightly-report-trigger \
--location $REGION \
--schedule "0 2 * * *" --time-zone "Etc/UTC" \
--uri "https://run.googleapis.com/v2/projects/$PROJECT_ID/locations/$REGION/jobs/$JOB:run" \
--http-method POST \
--oauth-service-account-email report-scheduler@$PROJECT_ID.iam.gserviceaccount.com
# Test it now
gcloud scheduler jobs run nightly-report-trigger --location $REGION
Official docs: Execute jobs on a schedule, Cloud Scheduler — schedule a job, gcloud scheduler jobs create http.
Cloud Scheduler is billed per scheduler job per month with a small free allowance; check the
Cloud Scheduler pricing page. Longer multi-step processes (import, then
report, then notify) are better composed with Workflows, which can start a job and wait for it (the
googleapis.run.v2.projects.locations.jobs.run connector); see
Messaging and Integration. For Pub/Sub-driven work use a push subscription to a service
or a worker pool below.
Worker pools
A worker pool is Cloud Run’s resource for continuous background work that has no incoming HTTP: a Pub/Sub pull subscriber, a Kafka consumer or a queue-draining process. It became generally available on 2026-04-14. Compared with services, a worker pool has no endpoint and does not scale on requests; compared with jobs, it is not expected to exit. Scaling is manual: you set the instance count, and you scale it from your own signal (queue depth) with a script, or with an external autoscaler.
gcloud run worker-pools deploy notifier-pull --region $REGION \
--image $REGION-docker.pkg.dev/$PROJECT_ID/bookshelf/notifier:v1 \
--service-account notifier@$PROJECT_ID.iam.gserviceaccount.com \
--instances 2
gcloud run worker-pools update notifier-pull --region $REGION --instances 5
gcloud run worker-pools update notifier-pull --region $REGION --instances 0 # stop it
gcloud run worker-pools list --region $REGION
Official docs: Deploy worker pools, Manual scaling for worker pools, gcloud run worker-pools.
Worker pool names are at most 49 characters and unique per region and project. The deployer needs
roles/run.developer, roles/iam.serviceAccountUser on the runtime service account and
roles/artifactregistry.reader for the image. All requested instances are billed as active whether busy or idle, so
the instance count is the cost lever; see the pricing page for regional tiers.
In the console: Cloud Run, Worker pools, Deploy container, select the image, name, region, and in Scaling the instance count.
Pull consumer in Java using Application Default Credentials (the pool’s service account needs
roles/pubsub.subscriber on the subscription):
package com.example.bookshelf.notifier;
import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
public class NotifierWorker {
public static void main(String[] args) throws InterruptedException {
String projectId = System.getenv("GOOGLE_CLOUD_PROJECT");
ProjectSubscriptionName subscription = ProjectSubscriptionName.of(projectId, "orders-notifier-sub");
MessageReceiver receiver = (PubsubMessage message, AckReplyConsumer consumer) -> {
try {
sendConfirmationEmail(message.getData().toStringUtf8());
consumer.ack();
} catch (RuntimeException e) {
consumer.nack();
}
};
Subscriber subscriber = Subscriber.newBuilder(subscription, receiver).build();
subscriber.startAsync().awaitRunning();
subscriber.awaitTerminated(); // the pool keeps running until stopped
}
private static void sendConfirmationEmail(String orderJson) { /* call the e-mail relay */ }
}
Official docs: Pub/Sub pull subscriptions and
Pub/Sub client libraries. The
event-driven (push) alternative for the same notifier is in
Cloud Run Functions and Events; pull with a worker pool suits high throughput and
controlled concurrency, while push to a service scales to zero and needs no code to poll.
Instances
A Cloud Run instance (Preview, the gcloud beta run instances surface) is an individually addressable singleton
container that you start, stop and delete yourself, without a service or autoscaling. It targets one-off or
long-lived single-container workloads such as a development environment or a stateful agent. As a Preview feature it
is not covered by an SLA, may change, and is not available in every region (the documentation lists excluded regions);
confirm status in the release notes before depending on it.
gcloud beta run instances create dev-sandbox --region $REGION \
--image $REGION-docker.pkg.dev/$PROJECT_ID/bookshelf/catalog-api:v2
gcloud beta run instances delete dev-sandbox --region $REGION
Official docs: Create and manage Cloud Run instances, gcloud beta run instances create.
GPUs
Cloud Run services and jobs can attach one GPU per instance (NVIDIA L4 and RTX PRO 6000 Blackwell are listed, in specific regions; services reached general availability on 2025-04-07). GPU instances use instance-based billing, still scale to zero, start in a few seconds and require a larger minimum of CPU and memory (for the L4, at least 4 vCPU and 16 GiB). Zonal redundancy is on by default, which reserves capacity across zones at a higher cost; turning it off saves money but offers only best-effort failover. A GPU job task has a maximum timeout of one hour. New projects get a small starter GPU quota; more requires a quota request.
gcloud run services update $SERVICE --region $REGION --gpu 1 --gpu-type nvidia-l4 \
--cpu 4 --memory 16Gi --no-cpu-throttling
Official docs: GPU support for services, GPU support for jobs. Bookshelf has no GPU workload; the managed AI services are in AI, Data and Analytics Overview.
Quotas and limits
Limits change; the authoritative table is the Cloud Run quotas page. Values below were checked on 2026-09-30.
| Item | Limit |
|---|---|
Request timeout (services) |
Up to 60 minutes |
Concurrent requests per instance |
Default 80, maximum 1,000 |
CPU / memory per instance |
Up to 8 vCPU / 32 GiB (GPU configurations require more) |
Max instances |
Region quota based; default applied to every service |
Revisions per service |
1,000 non-addressable revisions (older ones are deleted automatically) |
Revisions serving traffic |
4,000 per project and region |
Revision tags |
2,000 per project and region |
Services per project and region |
1,000 |
Job task timeout |
Up to 168 hours (1 hour with GPUs) |
Tasks per job execution |
10,000 |
Task retries |
10 per task |
Job executions |
1,000 per project and region (1,000 retained per job) |
Worker pools |
1,000 per project and region; name up to 49 characters |
Troubleshooting
- Requests return 429
-
Max instances or the regional quota is reached, or the queue wait exceeded its limit during a spike. Raise
--maxor the quota, increase concurrency, lower startup time, add--min. - Requests return 503
-
No instance became ready, usually because the container does not listen on
$PORTfast enough, crashes at start or fails its probes. Checkgcloud run services logs readand the revision’s Conditions. - Requests return 504
-
The request exceeded the request timeout. Raise
--timeout(up to 60 minutes) or move long work to a job. - Slow first requests
-
Cold starts. Use
--cpu-boost,--min 1, smaller images and lazy initialisation. - Costs keep rising after a canary
-
A tagged revision with min instances, or a forgotten tag, is still running; run
gcloud run services describeand remove the tag. - Traffic split ignores a new deploy
-
The service is routed to a named revision; use
--to-latestor the tag flow above. - Job fails with exit code 137
-
Out of memory. Raise
--memoryor process data in smaller shards. - Job tasks restart forever
-
Retries are exhausted at
--max-retries; the execution then fails. Check the task’s logs for the attempt number inCLOUD_RUN_TASK_ATTEMPT. - Scheduler trigger returns 403
-
The scheduler service account lacks
roles/run.invokeron the job, or an OIDC token was used where the Admin API needs an OAuth token. - Worker pool shows no activity
-
Instances are 0, the service account lacks
roles/pubsub.subscriber, or the subscription is wrong.
Official docs: Troubleshoot Cloud Run issues.
Clean up
gcloud scheduler jobs delete nightly-report-trigger --location $REGION --quiet
gcloud run jobs delete $JOB --region $REGION --quiet
gcloud run worker-pools delete notifier-pull --region $REGION --quiet
gcloud beta run instances delete dev-sandbox --region $REGION --quiet
# remove tags and extra revisions on the service, then the service itself if it was only for the exercise
gcloud run services update-traffic $SERVICE --region $REGION --clear-tags
gcloud run services update $SERVICE --region $REGION --scaling auto --min 0
gcloud run services delete $SERVICE --region $REGION --quiet
gcloud iam service-accounts delete report-scheduler@$PROJECT_ID.iam.gserviceaccount.com --quiet
Official docs: gcloud run services delete, gcloud scheduler jobs delete. If you deployed a multi-region service, delete it with the same command, which also removes the load balancer resources it created. Deleting a throwaway project removes everything at once after a retention period.
Related pages
-
Cloud Run covers service deployment, configuration, identity, networking and custom domains.
-
Cloud Run Functions and Events covers event-driven functions and Eventarc.
-
Load Balancing and Cloud Armor covers the global load balancer used for multi-region services and custom domains.
-
Monitoring and Observability covers the logs and metrics used to judge a canary.
-
Orchestration: Swarm Mode and Kubernetes covers generic container orchestration concepts.
-
ECS Deployments, Scaling and Networking and Azure are the AWS and Azure counterparts.