Entorno de ejecución de Cloud Functions

Cloud Functions se ejecuta en un entorno sin servidores y completamente administrado en el que Google se encarga de la infraestructura, los sistemas operativos y los entornos de ejecución. Cada función se ejecuta en un contexto propio, seguro y aislado, se escala automáticamente y cuenta con un ciclo de vida independiente de otras funciones.

Entornos de ejecución

Cloud Functions admite varios entornos de ejecución de lenguajes. Cada uno contiene un conjunto estándar de paquetes de sistema, así como las herramientas y bibliotecas necesarias para ese lenguaje. Necesitarás el valor del ID del entorno de ejecución si implementas funcionesdesde la línea de comandos o medianteTerraform.

Las actualizaciones de seguridad y mantenimiento están disponibles para todos los entornos de ejecución de 1a y 2a gen. Estas actualizaciones se aplican de forma automática o manual, según el entorno y la configuración. Para obtener más información sobre las actualizaciones del entorno de ejecución, consulta Protege tu Cloud Function.

Node.js

Entorno de ejecución Generación Entorno ID de entorno de ejecución Imagen del entorno de ejecución Baja Desmantela
Node.js 20 1st gen, 2nd gen Ubuntu 22.04 nodejs20 gcr.io/gae-runtimes/buildpacks/nodejs20/run 2026-04-30
Node.js 18 1st gen, 2nd gen Ubuntu 22.04 nodejs18 gcr.io/gae-runtimes/buildpacks/nodejs18/run 2025-04-30
Node.js 16 1st gen, 2nd gen Ubuntu 18.04 nodejs16 gcr.io/gae-runtimes/buildpacks/nodejs16/run 2024-01-30
Node.js 14 1st gen, 2nd gen Ubuntu 18.04 nodejs14 gcr.io/gae-runtimes/buildpacks/nodejs14/run 2024-01-30
Node.js 12 1st gen, 2nd gen Ubuntu 18.04 nodejs12 gcr.io/gae-runtimes/buildpacks/nodejs12s/run 2024-01-30
Node.js 10 1st gen, 2nd gen Ubuntu 18.04 nodejs10 gcr.io/gae-runtimes/buildpacks/nodejs10/run 2024-01-30
Node.js 8 1st gen, 2nd gen Ubuntu 18.04 nodejs8 gcr.io/gae-runtimes/buildpacks/nodejs8/run 05-06-2020 Feb de 2021
Node.js 6 1st gen, 2nd gen Ubuntu 18.04 nodejs6 gcr.io/gae-runtimes/buildpacks/nodejs6/run 2019-04-17 Ago de 2020

Python

Entorno de ejecución Generación Entorno ID de entorno de ejecución Imagen del entorno de ejecución Baja Desmantela
Python 3.12 1st gen, 2nd gen Ubuntu 22.04 Python312 gcr.io/gae-runtimes/buildpacks/python312/run 02-10-2028
Python 3.11 1st gen, 2nd gen Ubuntu 22.04 python311 gcr.io/gae-runtimes/buildpacks/python311/run 2027-10-24
Python 3.10 1st gen, 2nd gen Ubuntu 22.04 python310 gcr.io/gae-runtimes/buildpacks/python310/run 2026-10-04
Python 3.9 1st gen, 2nd gen Ubuntu 18.04 python39 gcr.io/gae-runtimes/buildpacks/python39/run 2025-10-05
Python 3.8 1st gen, 2nd gen Ubuntu 18.04 python38 gcr.io/gae-runtimes/buildpacks/python38/run 14-10-2024
Python 3.7 1ª gen. Ubuntu 18.04 python37 gcr.io/gae-runtimes/buildpacks/python37/run 2024-01-30

Comienza a usarlo

Entorno de ejecución Generación Entorno ID de entorno de ejecución Imagen del entorno de ejecución Baja Desmantela
Go 1.22 2ª gen. Ubuntu 22.04 go122 gcr.io/gae-runtimes/buildpacks/go122/run
Go 1.21 1st gen, 2nd gen Ubuntu 22.04 go121 gcr.io/gae-runtimes/buildpacks/go121/run
Go 1.20 1st gen, 2nd gen Ubuntu 22.04 go120 gcr.io/gae-runtimes/buildpacks/go120/run
Go 1.19 1st gen, 2nd gen Ubuntu 22.04 go119 gcr.io/gae-runtimes/buildpacks/go119/run 30-04-2024
Go 1.18 1st gen, 2nd gen Ubuntu 22.04 go118 gcr.io/gae-runtimes/buildpacks/go118/run 2024-01-30
Go 1.16 1st gen, 2nd gen Ubuntu 18.04 go116 gcr.io/gae-runtimes/buildpacks/go116/run 2024-01-30
Go 1.13 1st gen, 2nd gen Ubuntu 18.04 go113 gcr.io/gae-runtimes/buildpacks/go113/run 2024-01-30
Go 1.12 1st gen, 2nd gen Ubuntu 18.04 go112 gcr.io/gae-runtimes/buildpacks/go112/run 2024-01-30
Go 1.11 1st gen, 2nd gen Ubuntu 18.04 go111 gcr.io/gae-runtimes/buildpacks/go111/run 2020-08-05 Feb de 2021

Java

Entorno de ejecución Generación Entorno ID de entorno de ejecución Imagen del entorno de ejecución Baja Desmantela
Java 21 2ª gen. Ubuntu 22.04 java21 gcr.io/gae-runtimes/buildpacks/java21/run Octubre de 2031
Java 17 1st gen, 2nd gen Ubuntu 22.04 java17 gcr.io/gae-runtimes/buildpacks/java17/run Octubre de 2027
Java 11 1st gen, 2nd gen Ubuntu 18.04 java11 gcr.io/gae-runtimes/buildpacks/java11/run Octubre de 2024

Ruby

Entorno de ejecución Generación Entorno ID de entorno de ejecución Imagen del entorno de ejecución Baja Desmantela
Ruby 3.2 1st gen, 2nd gen Ubuntu 22.04 ruby32 gcr.io/gae-runtimes/buildpacks/ruby32/run 2026-03-31
Ruby 3.0 1st gen, 2nd gen Ubuntu 18.04 ruby30 gcr.io/gae-runtimes/buildpacks/ruby30/run 2024-03-31
Ruby 2.7 1st gen, 2nd gen Ubuntu 18.04 ruby27 gcr.io/gae-runtimes/buildpacks/ruby27/run 2024-01-30
Ruby 2.6 1st gen, 2nd gen Ubuntu 18.04 ruby26 gcr.io/gae-runtimes/buildpacks/ruby26/run 2024-01-30

PHP

Entorno de ejecución Entorno Generación ID de entorno de ejecución Imagen del entorno de ejecución Baja Desmantela
PHP 8.3 2ª gen. Ubuntu 22.04 php83 gcr.io/gae-runtimes/buildpacks/php83/run 2026-11-23 2027-11-23
PHP 8.2 1st gen, 2nd gen Ubuntu 22.04 php82 gcr.io/gae-runtimes/buildpacks/php82/run 2025-12-08
PHP 8.1 1st gen, 2nd gen Ubuntu 18.04 php81 gcr.io/gae-runtimes/buildpacks/php81/run 2024-11-25
PHP 7.4 1st gen, 2nd gen Ubuntu 18.04 php74 gcr.io/gae-runtimes/buildpacks/php74/run 2024-01-30

.NET Core

Entorno de ejecución Generación Entorno ID de entorno de ejecución Imagen del entorno de ejecución Baja Desmantela
.NET Core 8 2ª gen. Ubuntu 22.04 dotnet8 gcr.io/gae-runtimes/buildpacks/dotnet8/run
.NET Core 6 1st gen, 2nd gen Ubuntu 22.04 dotnet6 gcr.io/gae-runtimes/buildpacks/dotnet6/run 12-11-2024
.NET Core 3 1st gen, 2nd gen Ubuntu 18.04 dotnet3 gcr.io/gae-runtimes/buildpacks/dotnet3/run 2024-01-30

Comportamiento del ajuste de escala automático

Cloud Functions implementa el paradigma sin servidores, en el que solo ejecutas el código sin preocuparte por la infraestructura subyacente, como los servidores o las máquinas virtuales. Una vez implementadas, las funciones se administran y escalan de forma automática.

Cloud Functions maneja las solicitudes entrantes asignándolas a las instancias de tu función. Dependiendo del volumen de solicitudes, así como de la cantidad de instancias de funciones existentes, Cloud Functions puede asignar una solicitud a una instancia existente o crear una nueva.

En los casos en que el volumen de solicitudes entrantes exceda la cantidad de instancias existentes, Cloud Functions puede iniciar varias instancias nuevas para manejar las solicitudes. Este comportamiento de ajuste de escala automático permite que Cloud Functions maneje muchas solicitudes en paralelo, cada una a través de una instancia diferente de la función.

En algunos casos, no se recomienda el escalamiento ilimitado. A fin de solucionar este problema, Cloud Functions te permite configurar una cantidad máxima de instancias que pueden coexistir en un momento determinado para una función en particular.

Sin estado

Para habilitar la administración automática y el escalamiento de tus funciones, las funciones deben ser sin estado: una invocación de función no debe basarse en un estado de la memoria configurado por una invocación previa. Las invocaciones pueden controlarse mediante diferentes instancias de funciones, que no comparten variables globales, memoria, sistemas de archivos ni otro estado.

Si necesitas compartir estados en las invocaciones de función, la función debe usar un servicio como Memorystore, Datastore, Firestore o Cloud Storage para conservar los datos. Consulta las bases de datos de Google Cloud y los productos de almacenamiento de Google Cloud para obtener más información sobre las opciones de bases de datos y almacenamiento que proporciona Google Cloud.

Simultaneidad

Cloud Functions (2nd gen)

Cloud Functions (2nd gen) admite el manejo de varias solicitudes simultáneas en una sola instancia de función. Esto puede ser útil para prevenir inicios en frío, ya que una instancia ya preparada puede procesar varias solicitudes de forma simultánea, lo que reduce la latencia general. Para obtener más información, consulta Simultaneidad.

Cloud Functions (1st gen)

En Cloud Functions (1st gen), cada instancia de una función maneja solo una solicitud simultánea a la vez. Esto significa que mientras tu código procesa una solicitud, no hay posibilidad de que una segunda solicitud se enrute a la misma instancia. Por lo tanto, la solicitud original puede usar la cantidad total de recursos (memoria y CPU) que asignas.

Dado que diferentes instancias de función procesan solicitudes simultáneas en Cloud Functions (1st gen), no comparten variables ni memoria local. Consulta Sin estado y Ciclo de vida de la instancia de función para obtener más información.

Inicios en frío

Una instancia de función nueva se inicia en dos casos:

  • Cuando implementas la función.

  • Cuando una instancia de función nueva se crea automáticamente para escalar verticalmente hasta la carga o, de manera ocasional, a fin de reemplazar una instancia existente.

Iniciar una instancia de función nueva implica cargar el entorno de ejecución y tu código. Las solicitudes que incluyen el inicio de instancias de función, llamadas inicios en frío, pueden ser más lentas que las que se enrutan a instancias de función existentes. Sin embargo, si tu función recibe una carga constante, la cantidad de inicios en frío suele ser insignificante, a menos que la función falle con frecuencia y requiera el reinicio del entorno de la función.

Si el código de tu función genera una excepción no detectada o hace que falle el proceso actual, la instancia de función puede reiniciarse. Esto puede generar inicios más en frío, lo que da como resultado una latencia más alta, por lo que recomendamos capturar excepciones y, de lo contrario, evitar la finalización del proceso actual. Consulta Informa errores para obtener una explicación sobre cómo manejar y, luego, informar errores en Cloud Functions.

Si tu función es sensible a la latencia, considera establecer una cantidad mínima de instancias para evitar inicios en frío.

Vida útil de la instancia de función

Por lo general, las instancias de función son resilientes y se vuelven a usar en invocaciones de funciones posteriores, a menos que se reduzca la cantidad de instancias verticalmente debido a la falta de tráfico en curso o a que tu función falle. Esto significa que, cuando la ejecución de una función termina, la misma instancia de función puede controlar otra invocación de función.

Alcance de la función vs. alcance global

La invocación de una sola función da como resultado la ejecución del cuerpo de la función declarada solamente como el punto de entrada. El alcance global del código fuente de tu función solo se ejecuta en inicios en frío y no en instancias que ya se inicializaron.

Node.js

const functions = require('@google-cloud/functions-framework');

// TODO(developer): Define your own computations
const {lightComputation, heavyComputation} = require('./computations');

// Global (instance-wide) scope
// This computation runs once (at instance cold-start)
const instanceVar = heavyComputation();

/**
 * HTTP function that declares a variable.
 *
 * @param {Object} req request context.
 * @param {Object} res response context.
 */
functions.http('scopeDemo', (req, res) => {
  // Per-function scope
  // This computation runs every time this function is called
  const functionVar = lightComputation();

  res.send(`Per instance: ${instanceVar}, per function: ${functionVar}`);
});

Python

import time

import functions_framework

# Placeholder
def heavy_computation():
    return time.time()

# Placeholder
def light_computation():
    return time.time()

# Global (instance-wide) scope
# This computation runs at instance cold-start
instance_var = heavy_computation()

@functions_framework.http
def scope_demo(request):
    """
    HTTP Cloud Function that declares a variable.
    Args:
        request (flask.Request): The request object.
        <http://flask.pocoo.org/docs/1.0/api/#flask.Request>
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using `make_response`
        <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>.
    """

    # Per-function scope
    # This computation runs every time this function is called
    function_var = light_computation()
    return f"Instance: {instance_var}; function: {function_var}"

Go


// h is in the global (instance-wide) scope.
var h string

// init runs during package initialization. So, this will only run during an
// an instance's cold start.
func init() {
	h = heavyComputation()
	functions.HTTP("ScopeDemo", ScopeDemo)
}

// ScopeDemo is an example of using globally and locally
// scoped variables in a function.
func ScopeDemo(w http.ResponseWriter, r *http.Request) {
	l := lightComputation()
	fmt.Fprintf(w, "Global: %q, Local: %q", h, l)
}

Java


import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

public class Scopes implements HttpFunction {
  // Global (instance-wide) scope
  // This computation runs at instance cold-start.
  // Warning: Class variables used in functions code must be thread-safe.
  private static final int INSTANCE_VAR = heavyComputation();

  @Override
  public void service(HttpRequest request, HttpResponse response)
      throws IOException {
    // Per-function scope
    // This computation runs every time this function is called
    int functionVar = lightComputation();

    var writer = new PrintWriter(response.getWriter());
    writer.printf("Instance: %s; function: %s", INSTANCE_VAR, functionVar);
  }

  private static int lightComputation() {
    int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    return Arrays.stream(numbers).sum();
  }

  private static int heavyComputation() {
    int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    return Arrays.stream(numbers).reduce((t, x) -> t * x).getAsInt();
  }
}

Rita

# Global (instance-wide) scope.
# This block runs on cold start, before any function is invoked.
#
# Note: It is usually best to run global initialization in an on_startup block
# instead at the top level of the Ruby file. This is because top-level code
# could be executed to verify the function during deployment, whereas an
# on_startup block is run only when an actual function instance is starting up.
FunctionsFramework.on_startup do
  instance_data = perform_heavy_computation

  # To pass data into function invocations, the best practice is to set a
  # key-value pair using the Ruby Function Framework's built-in "set_global"
  # method. Functions can call the "global" method to retrieve the data by key.
  # (You can also use Ruby global variables or "toplevel" local variables, but
  # they can make it difficult to isolate global data for testing.)
  set_global :my_instance_data, instance_data
end

FunctionsFramework.http "tips_scopes" do |_request|
  # Per-function scope.
  # This method is called every time this function is called.
  invocation_data = perform_light_computation

  # Retrieve the data computed by the on_startup block.
  instance_data = global :my_instance_data

  "instance: #{instance_data}; function: #{invocation_data}"
end

Puedes usar variables globales como una optimización del rendimiento, pero no debes confiar en el estado establecido en el alcance global mediante invocaciones de funciones anteriores. Consulta Sin estado para obtener más información.

Puedes suponer que, para cada instancia de función, el alcance global se ejecutó solo una vez antes de que se invocara el código de la función. Sin embargo, no debes depender de la cantidad total de ejecuciones de alcance global o de su tiempo, ya que pueden variar según la actividad de ajuste de escala automático.

Cronograma de ejecución de funciones

Una función tiene acceso a sus recursos asignados (memoria y CPU) solo por el tiempo que dura la ejecución de la función. El código que se ejecuta fuera del período de ejecución no tiene garantía de ejecutarse y puede detenerse en cualquier momento. Por lo tanto, siempre debes indicar el final de la ejecución de tu función de forma correcta y evitar ejecutar cualquier otro código. Consulta las funciones de HTTP, las funciones en segundo plano y las funciones de CloudEvent para obtener asesoramiento.

La ejecución de la función también está sujeta a la duración de tiempo de espera de la función. Consulta Tiempo de espera de la función para obtener más información.

Ten en cuenta el cronograma de ejecución cuando inicialices la aplicación. Las tareas en segundo plano no deben crearse en el alcance global durante la inicialización, ya que se ejecutan fuera de la duración de una solicitud.

Garantías de ejecución

Por lo general, las funciones se invocan una vez por cada evento entrante. Sin embargo, Cloud Functions no garantiza una sola invocación en todos los casos debido a las diferencias en las situaciones de error.

La cantidad máxima o mínima de veces que tu función puede invocarse para un solo evento depende del tipo de función.

  • Las funciones de HTTP se invocan máximo una vez. Esto se debe a la naturaleza síncrona de las llamadas a HTTP y quiere decir que se mostrará cualquier error que ocurra durante la invocación de función sin reintentar el proceso. Se espera que el emisor de una función de HTTP corrija los errores y vuelva a intentar el proceso si es necesario.

  • Las funciones controladas por eventos se invocan mínimo una vez. Esto se debe a su naturaleza asíncrona del manejo de eventos, en la que no hay ningún emisor que espere por la respuesta. En extrañas circunstancias, el sistema podría invocar una función controlada por eventos más de una vez con el fin de asegurar el envío del evento. Si la invocación de una función controlada por eventos falla con un error, no se invocará de nuevo, a menos que se habiliten opciones para esa función que permitan reintentar el proceso en caso de error.

Para asegurarte de que tu función se comporta correctamente en los demás intentos de ejecución, debes hacerla idempotente mediante su implementación, de manera que se produzcan los resultados deseados (y efectos secundarios) incluso si un evento se entrega varias veces. En el caso de las funciones de HTTP, esto también implica mostrar el valor deseado, incluso si el emisor vuelve a intentar las llamadas al extremo de la función de HTTP. Consulta Reintenta las funciones controladas por eventos para obtener más información sobre cómo hacer que tu función sea idempotente.

Memoria y sistema de archivos

Cada función tiene una cierta cantidad de memoria asignada para su uso. Puedes configurar la cantidad de memoria en la implementación; consulta Límites de memoria para obtener más información.

El entorno de ejecución de funciones incluye un sistema de archivos en la memoria que contiene los archivos de origen y los directorios implementados con la función (consulta Estructura código fuente). El directorio que contiene tus archivos de origen es de solo lectura, pero el resto del sistema de archivos puede escribirse (excepto los archivos que usa el sistema operativo). El uso del sistema de archivos se considera dentro del uso de memoria de una función.

Tu función puede interactuar con el sistema de archivos mediante métodos estándar en cada lenguaje de programación.

Red

Tu función puede acceder a la red pública de Internet con métodos estándar en cada lenguaje de programación, ya sea a través de bibliotecas integradas que ofrece el entorno de ejecución o bibliotecas de terceros que incluyas como dependencias.

Vuelve a usar las conexiones de red en las invocaciones de funciones, como se describe en Optimiza las Herramientas de redes. Sin embargo, ten en cuenta que el sistema podría cerrar una conexión que permanece 10 minutos sin usarse y que los intentos adicionales para usar una conexión cerrada podrían dar como resultado un error de “restablecimiento de la conexión”. El código debe usar una biblioteca que administre bien las conexiones cerradas o que las administre de manera explícita si usa construcciones de herramientas de redes de nivel inferior.

Aislamiento de funciones

Cada función implementada se aísla de todas las demás funciones, incluso de aquellas implementadas desde el mismo archivo fuente. En particular, no comparten memoria, variables globales, sistemas de archivos ni otros estados.

Para compartir datos entre las funciones implementadas, puedes usar servicios como Memorystore, Datastore, Firestore o Cloud Storage. De manera alternativa, puedes invocar una función desde otra con los activadores apropiados y pasar los datos necesarios. Por ejemplo, realiza una solicitud HTTP al extremo de una función de HTTP o publica un mensaje en un tema de Pub/Sub para activar una función de Pub/Sub.