Nico Bargioni
Cloud Run & Functions
#cloud-run#serverless#curiosidades

Por qué Cloud Run te obliga a ser stateless

Guardás un archivo en disco, funciona, y dos requests después desapareció. No es un bug: es la regla de oro de Cloud Run.

Subís una imagen, la guardás en /tmp, devolvés la URL. Andás a buscarla un rato después y no está. O peor: a veces está y a veces no, sin patrón aparente. No te volviste loco. Cloud Run no te deja guardar estado local, y entender por qué te ahorra horas de debugging que parece embrujado.

La causa: tu contenedor es desechable

Cloud Run no corre un servidor; corre contenedores efímeros que va creando y destruyendo según el tráfico. Tres consecuencias que rompen el modelo mental de "un servidor de toda la vida":

  • Escala a cero. Sin tráfico, se apaga todo y con ello la RAM y el disco local. Lo que guardaste, desapareció.
  • Escala horizontal. Con tráfico, levanta varias instancias. La request que guardó el archivo y la que lo busca pueden caer en contenedores distintos, cada uno con su propio disco.
  • Reemplazo en cada deploy. Cada versión nueva tira los contenedores viejos. No hay continuidad.

Por eso el disco local de Cloud Run es realmente memoria RAM temporal: rápido, sí, pero se evapora. Sirve de scratch dentro de una misma request, nunca como almacenamiento.

Stateless no es una opción, es la arquitectura

"Stateless" suena a jerga, pero significa algo concreto: cada request se atiende sin depender de lo que quedó de las anteriores en esa instancia. Toda la información que tiene que sobrevivir vive afuera del contenedor:

  • Archivos → un bucket de almacenamiento de objetos (Cloud Storage).
  • Datos estructurados → una base administrada (Postgres, Firestore, BigQuery para analítica).
  • Sesiones / caché → un store compartido como Redis, no una variable global en memoria.
  • Trabajo diferido → una cola de mensajes, no un thread que arrancaste y esperás que siga vivo.
# MAL: se pierde al apagarse o al escalar a otra instancia
uploads = {}
@app.post("/subir")
def subir(f):
    uploads[f.id] = f.bytes   # vive solo en ESTA instancia

# BIEN: el estado vive afuera, lo ve cualquier instancia
@app.post("/subir")
def subir(f):
    bucket.blob(f.id).upload_from_string(f.bytes)

La incomodidad que en realidad es un regalo

Al principio molesta: tenés que sacar el estado de adentro de la app y mandarlo a otro servicio. Pero esa misma restricción es lo que te da escalado automático sin dolor. Como ningún contenedor es especial, la plataforma puede crear, matar y reemplazar instancias libremente. Es el mismo principio que hace reproducible a un contenedor de Docker: si no dependés del entorno local, corre igual en cualquier lado.

Nota relacionada

Cold starts: el medio segundo que arruina la experiencia

Tu API responde en 50 ms... salvo la primera request, que tarda 3 segundos. Eso es un cold start, y casi siempre se puede domar.

Leer nota

Lo stateless es la condición que hace posible el scale-to-zero y el escalado horizontal que tanto te gustan. No es un capricho de Cloud Run: es el peaje que pagás por no administrar servidores. Y casi siempre vale la pena pagarlo.

Compartir

¿Lo necesitás en tu negocio?

Seguí explorando