Region ID
The REGION_ID
is an abbreviated code that Google assigns
based on the region you select when you create your app. The code does not
correspond to a country or province, even though some region IDs may appear
similar to commonly used country and province codes. For apps created after
February 2020, REGION_ID.r
is included in
App Engine URLs. For existing apps created before this date, the
region ID is optional in the URL.
Learn more about region IDs.
This guide provides an introduction to Cloud Run for those who are familiar with App Engine. It covers the key similarities and differences between the Serverless platforms to help prepare for migration from either App Engine standard environment or App Engine flexible environment.
Overview
Cloud Run is the latest evolution of Google Cloud Serverless, building on the experience of running App Engine for more than a decade. Cloud Run runs on much of the same infrastructure as App Engine standard environment, so there are many similarities between these two platforms.
Cloud Run is designed to improve upon the App Engine experience, incorporating many of the best features of both App Engine standard environment and App Engine flexible environment. Cloud Run services can handle the same workloads as App Engine services, but Cloud Run offers customers much more flexibility in implementing these services. This flexibility, along with improved integrations with both Google Cloud and third-party services, also enables Cloud Run to handle workloads that cannot run on App Engine.
Comparison summary
While there are many similarities and differences between App Engine and Cloud Run, this overview focuses on the areas that are most relevant for App Engine customers getting started with Cloud Run.
App Engine standard environment | App Engine flexible environment | Cloud Run | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Terminology | Application | N/A | |||||||||||||||||||
Service | Service | ||||||||||||||||||||
Version | Revision | URL endpoints |
|||||||||||||||||||
App URL
( default service)
|
https://PROJECT_ID.REGION_ID.r.appspot.com
|
N/A | |||||||||||||||||||
Service URL |
https://SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com
|
|
|||||||||||||||||||
Version/Revision URL |
https://VERSION-dot-SERVICE-dot-PROJECT_ID.REGION_ID.r.appspot.com
|
|
Scaling |
||||||||||||||||||
Automatic scaling | Yes | Yes | Yes | ||||||||||||||||||
Manual scaling | Yes | Yes | While there is no specific manual scaling setting, the same behavior can be replicated by configuring maximum instances equal to minimum instances | ||||||||||||||||||
Scale-to-zero | Yes | No | Yes | ||||||||||||||||||
Warm-up requests | Configurable | No | Automatic | ||||||||||||||||||
Idle instance timeout (after finishing last request) | Up to 15 minutes | Depends on CPU allocation setting. Use CPU always allocated to emulate App Engine behavior | |||||||||||||||||||
Request timeout |
|
60 minutes | Configurable up to 60 minutes (default: 5 minutes) | Deployment |
|||||||||||||||||
From source | Yes | Yes | |||||||||||||||||||
Container image | No | Yes (custom runtimes) | Yes | Compute resources |
|||||||||||||||||
vCPU |
|
Up to 80 vCPU | Up to 8 vCPU | ||||||||||||||||||
Memory | Up to 6.5GB per vCPU | Up to 32GB | Pricing model |
||||||||||||||||||
Per-request fee | No |
No, when CPU is always allocated. Yes, when CPU is only allocated during request processing. |
|||||||||||||||||||
Idle minimum instances | Same cost as active instances | Lower cost for idle minimum instances (see Billable container instance time) | |||||||||||||||||||
Committed use discounts (CUDs) | No | Yes | Security |
||||||||||||||||||
Ingress settings | Yes | Yes | Yes | ||||||||||||||||||
Invoker role | No | Yes | |||||||||||||||||||
IAP | Yes | Yes | Configure using Cloud Load Balancing | ||||||||||||||||||
Firewalls | Yes | Yes | Configure using Google Cloud Armor | Connectivity |
|||||||||||||||||
Custom domains | Yes | Yes | Configure using Cloud Load Balancing | ||||||||||||||||||
VPC connectivity (including Shared VPC) | Yes | N/A | Yes | ||||||||||||||||||
VPC egress settings | Yes | N/A | Yes | ||||||||||||||||||
Multi-region load-balancing | No | Yes | Accessing Google Cloud services |
||||||||||||||||||
Cloud SQL | Yes | Yes | Yes | ||||||||||||||||||
Cloud Client Libraries | If you are using Cloud Client Libraries in App Engine, you do not need to change anything when migrating to Cloud Run. These client libraries work everywhere, which means that your application is more portable. | ||||||||||||||||||||
App Engine legacy bundled services | Yes (Java, Python, Go, PHP only) | No | No |
Resource model
The Cloud Run resource model is very similar to App Engine, but there are some key differences:
- Cloud Run does not have a top-level Application resource, or the corresponding
default
service. - Cloud Run services in the same project can be deployed to different regions. In App Engine, all services in the project are in the same region.
- Cloud Run uses the term Revision, instead of Version, to align with the Knative resource model.
- Cloud Run revision names use the format:
SERVICE_NAME-REVISION_SUFFIX
, whereREVISION_SUFFIX
is either auto-generated, or set using the--revision-suffix=REVISION_SUFFIX
deployment flag. - Cloud Run revisions are immutable, meaning that you cannot reuse names like you can with App Engine versions (using the
--version=VERSION_ID
deployment flag). - Cloud Run service URLs are based on a Service Identifier that is automatically generated on the first deployment of the service. The Service Identifiers use the format:
SERVICE_NAME-<auto-generated identifier>
. The Service Identifier is unique, and does not change during the lifetime of the service. - In Cloud Run, only the service URLs (
SERVICE_IDENTIFIER.run.app
andhttps://SERVICE_NAME-PROJECT_NUMBER.REGION.run.app
) are exposed by default. To address a specific revision, you must configure a traffic tag. In App Engine, both the service and version URLs are exposed automatically.
Deployment and configuration
In App Engine, most configuration is done in the app.yaml
that is included in every deployment. This simplicity comes at a cost, in that, while a few settings can be updated using the Admin API, most changes require redeploying the service.
While Cloud Run has the service.yaml
configuration file, it is not used in the same way as the app.yaml
. The Cloud Run service.yaml
cannot be used when deploying from source, as one of the required elements is the path to the final container image. Also, the service.yaml
conforms to the Knative spec, and can be difficult to read for those not familiar with Kubernetes-style configuration files. For more information on using the service.yaml
to manage configuration, see the Cloud Run documentation.
For App Engine customers getting started with Cloud Run, using the gcloud CLI deployment flags aligns much more closely with the App Engine at-deployment configuration management.
To set the configuration when deploying new code in Cloud Run, use gcloud run deploy
flags:
gcloud run deploy SERVICE_NAME \
--cpu CPU \
--memory MEMORY \
--concurrency CONCURRENCY
While it is not necessary to use the configuration flags with every deployment (see Managing configurations), you can do so to help simplify configuration management.
In Cloud Run, you can also update the configuration without redeploying the source code using gcloud run services update
:
gcloud run services update SERVICE_NAME \
--cpu CPU \
--memory MEMORY \
--concurrency CONCURRENCY
As Cloud Run revisions are immutable, this command will create a new revision with the updated configuration, but will use the same container image as the existing revision.
Managing configurations
For App Engine deployments, all settings must be provided for every deployment, and any settings not provided are assigned default values. For example, take App Engine service-a
, with versions using the app.yaml
files shown below:
App Engine service-a version1 | App Engine service-a version2 |
---|---|
app.yaml | |
runtime: python39 service: service-a instance_class: F4 |
runtime: python39 service: service-a |
Applied configuration | |
runtime: python39 service: service-a instance_class: F4 default values: |
runtime: python39 service: service-a default values: |
version1
is configured with instance_class: F4
, while version2
, which provided no value for instance_class
, is configured with the default instance_class: F1
.
For Cloud Run, any configuration settings provided are applied, but any that are not provided keep their existing values. You only need to provide values for settings that you want to change. For example:
Cloud Run service-a revision1 | Cloud Run service-a revision2 |
---|---|
Deployment command | |
gcloud run deploy service-a \ --cpu=4 |
gcloud run deploy service-a |
Applied configuration | |
service: service-a vCPUs: 4 default values: |
service: service-a vCPUs: 4 default values: |
In App Engine, deploying with no configuration settings creates a version using all default settings. In Cloud Run, deploying with no configuration settings creates a revision using the same configuration settings as the previous revision. For the first revision of a Cloud Run service, deploying with no configuration settings creates a revision using all default settings.
Configuration defaults
Configuration setting | App Engine standard environment | App Engine flexible environment | Cloud Run |
---|---|---|---|
Compute resources | F1 | 1 vCPU, .6GB | 1 vCPU, 512MB |
Maximum concurrency (requests) | 10 | None | 80 |
Request timeout |
|
60 minutes | 5 minutes |
CPU utilization target | 60% | 50% | 60% |
Maximum instances | None | 20 | 100 |
Minimum instances | 0 | 2 | 0 |
Entrypoint
When deploying from source, App Engine reads the entrypoint command from the entrypoint
attribute in the app.yaml
. If no entrypoint is provided, a runtime-specific default is used. Cloud Run uses Google Cloud's buildpacks when deploying from source, and some languages do not have a default entrypoint, meaning you must provide one or the build will fail. For example, Python buildpacks require either a Procfile
, or specifying the GOOGLE_ENTRYPOINT
build environment variable.
Please review the buildpacks documentation for any language-specific configuration requirements.
Scaling
While Cloud Run and App Engine standard environment share much of the same scaling infrastructure, Cloud Run has been streamlined to enable much faster scaling. As part of this streamlining, the configurable settings are limited to:
- Maximum concurrency
- Maximum and Minimum instances
For Cloud Run instances, the target CPU utilization is not configurable, and fixed at 60%. See the Cloud Run documentation for more details about autoscaling.
App Engine flexible environment uses the Compute Engine Autoscaler, so has very different scaling characteristics than both App Engine standard environment and Cloud Run.
Idle instance timeout
In App Engine, idle instances remain alive for up to 15 minutes after the last request finished processing. Cloud Run allows you to configure this behavior using CPU allocation. To get the same behavior as App Engine, set the CPU allocation to CPU always allocated. Alternatively, use CPU only allocated during request processing to have idle instances shut down immediately (if there are no pending requests).
Warmup requests
Cloud Run automatically warms up instances using the
container entrypoint command,
so you do not need to manually enable warmup requests, or configure an
/_ah/warmup
handler. If you have code that you want to run at instance
startup, before any requests are processed, you can either:
Static content
In App Engine standard environment, you can serve static content without using compute resources by serving from Cloud Storage, or by configuring handlers. Cloud Run does not have the handlers option for serving static content, so you can either serve the content from the Cloud Run service (same as dynamic content), or from Cloud Storage.
Cloud Run Invoker role
Cloud Run also offers the ability to control access to a service with Identity and Access Management (IAM). The IAM policy bindings for a service can be set using the gcloud CLI, Console, or Terraform.
To replicate App Engine behavior, you can make the service public by allowing unauthenticated requests. This can be set at deployment, or by updating the IAM policy bindings on an existing Service.
Deployment
Use the --allow-unauthenticated
deployment flag:
gcloud run deploy SERVICE_NAME ... --allow-unauthenticated
Existing service
Use the gcloud run services add-iam-policy-binding
command:
gcloud run services add-iam-policy-binding SERVICE_NAME \ --member="allUsers" \ --role="roles/run.invoker"
where SERVICE_NAME
is the Cloud Run service name.
Alternatively, you can choose to control who has access to the service by granting the Cloud Run Invoker IAM role which is configurable per-service.
Deployment
gcloud run deploy SERVICE_NAME ... --no-allow-unauthenticated gcloud run services add-iam-policy-binding SERVICE_NAME \ --member=MEMBER_TYPE \ --role="roles/run.invoker"
where SERVICE_NAME
is the service name, and
MEMBER_TYPE
is the principal type. For example, user:email@domain.com
.
For a list of acceptable values for MEMBER_TYPE
, see
the IAM concepts page.
Existing service
gcloud run services add-iam-policy-binding SERVICE_NAME \ --member=MEMBER_TYPE \ --role="roles/run.invoker"
where SERVICE_NAME
is the service name, and
MEMBER_TYPE
is the principal type. For example, user:email@domain.com
.
For a list of acceptable values for MEMBER_TYPE
, see
the IAM concepts page.
Environment variables and metadata
Both App Engine and Cloud Run have certain environment variables that are automatically set. The table below shows the App Engine environment variables, along with their Cloud Run equivalents. Cloud Run only implements a few environment variables, as compared to App Engine, but the data available from the metadata server is mostly equivalent.
Default environment variables
App Engine Name | Cloud Run Name | Description |
---|---|---|
GAE_SERVICE
|
K_SERVICE
|
The name of the current service. In App Engine, this is set to `default` if not specified. |
GAE_VERSION
|
K_REVISION
|
The current version label of your service. |
PORT
|
PORT
|
The port that receives HTTP requests. |
N/A | K_CONFIGURATION
|
The name of the Cloud Run configuration that created the revision. |
GOOGLE_CLOUD_PROJECT
|
N/A | The Cloud project ID associated with your application. |
GAE_APPLICATION
|
The ID of your App Engine application. This ID is prefixed with 'region code~' such as 'e~' for applications deployed in Europe. | |
GAE_DEPLOYMENT_ID
|
The ID of the current deployment. | |
GAE_ENV
|
The App Engine environment. Set to `standard` if in the standard environment. | |
GAE_INSTANCE
|
The ID of the instance on which your service is currently running. | |
GAE_MEMORY_MB
|
The amount of memory available to the application process, in MB. | |
NODE_ENV (Only available in the Node.js runtime)
|
Set to production when your service is deployed. | |
GAE_RUNTIME
|
The runtime specified in your app.yaml file. |
Common metadata server paths
Path | Description | Example |
---|---|---|
/computeMetadata/v1/project/project-id
|
Project ID of the project the service belongs to | test_project |
/computeMetadata/v1/project/numeric-project-id
|
Project number of the project the service belongs to | 12345678912 |
/computeMetadata/v1/instance/id
|
Unique identifier of the container instance (also available in logs). | 16a61494692b7432806a16
(string of alpha-numeric characters) |
/computeMetadata/v1/instance/region
** Not available for App Engine flexible environment |
Region of this service, returns projects/PROJECT_NUMBER/regions/REGION
|
projects/12345678912/regions/us-central1 |
/computeMetadata/v1/instance/service-accounts/default/email
|
Email for the runtime service account of this service. | service_account@test_project.iam.gserviceaccount.com |
/computeMetadata/v1/instance/service-accounts/default/token
|
Generates an OAuth2 access token for the service account of this service. This endpoint will return a JSON response with an access_token attribute.
|
{ "access_token":"<TOKEN>", "expires_in":1799, "token_type":"Bearer" } |
What's next
- Quickstart: Deploy a web service with Cloud Run
- Is my app a good fit for Cloud Run?
- Migrate my App Engine custom domain to Cloud Load Balancing
- Other resources: