About execution environments

Cloud Run services by default don't have an execution environment specified, which means Cloud Run selects the execution environment based on the features used. So unless you specify an execution environment for your service, Cloud Run can select either the first generation or second generation environment.

Note that Cloud Run jobs only use the second generation execution environment, and this cannot be changed for jobs.

The first generation execution environment features fast cold start times and emulation of most, but not all operating system calls. Originally, this was the only execution environment available to services in Cloud Run.

The second generation execution environment provides full Linux compatibility rather than system call emulation. This execution environment provides:

  • Faster CPU performance
  • Faster network performance, especially in the presence of packet loss
  • Full Linux compatibility, including support for all system calls, namespaces, and cgroups
  • Network file system support

Although the second generation execution environment generally performs faster under sustained load, it has longer cold start times than first generation for most services.

You can select the execution environment for your Cloud Run service when you deploy a new service or a new revision of your service. If you don't specify an execution environment, first generation is used by default.

How to choose an execution environment

You should use first generation if any of the following apply:

  • Your Cloud Run service has bursty traffic, and needs to scale out fast to many instances, or your service is sensitive to cold start times.
  • Your Cloud Run service has infrequent traffic that causes frequent scale out from zero.
  • You want to use less than 512 MiB of memory. The second generation execution environment requires at least 512 MiB of memory.

You should use second generation if any of the following apply to your Cloud Run service:

  • Your service needs to use a network file system, which is only supported by second generation.
  • Your service has fairly steady traffic and is tolerant of somewhat slower cold starts.
  • Your service has CPU-intensive workloads.
  • Your service could benefit from faster network performance.
  • Your service needs to use software that has issues running in first generation due to unimplemented system calls.
  • Your service needs Linux cgroup functionality.
  • Your service makes use of third-party infrastructure for securing containers.

Best practices when using the second generation execution environment

We recommend that your container install a SIGTERM handler, especially if you are using request-based billing.

Handling SIGTERM gives your container a chance to perform any necessary cleanup tasks such as flushing logs before exiting. If your container does not catch SIGTERM, it will still be given 10 seconds to perform these tasks; those 10 seconds are billable.

How to check whether your container handles SIGTERM

To determine whether your container has a SIGTERM handler installed:

  1. Start Cloud Shell. You can find Activate Cloud Run button Activate Cloud Shell in the header of the documentation page you're on. You may need to authorize it and wait for it to provision. Alternatively, start a standalone session.

  2. Run the container locally in Cloud Shell:

    docker run IMAGE_URL

    Replace IMAGE_URL with a reference to the container image, for example, us-docker.pkg.dev/cloudrun/container/hello:latest. If you use Artifact Registry, the repository REPO_NAME must already be created. The URL has the shape LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG

  3. Open another tab in Cloud Shell and get a list of the containers running in the current Cloud Shell session:

    docker container ls

    You need to locate the container ID returned from the command.

  4. Using the container ID, send your container a SIGTERM signal

    docker kill -s SIGTERM CONTAINER_ID
  5. Return to the tab where you invoked docker run to see whether the container has exited (stopped). If the SIGTERM signal caused your container to exit, your container is handling SIGTERM.

How to handle SIGTERM

If your container does not handle SIGTERM, the simplest way to add a SIGTERM handler is to wrap your service with tini. Doing this makes your service run as a subprocess of tini, which takes on the role of the container init process. Refer to the Docker instructions for instructions.

Alternatively, you can change your application to directly handle SIGTERM.

What's next