Montar una API en Go sobre Cloud Run es, casi siempre, la decisión correcta: obtienes autoescalado gestionado, escalado a cero y contenedores sin tener que operar un clúster. Pero el coste de tu factura y tu latencia en el percentil 99 no dependen de Cloud Run, dependen de tres o cuatro parámetros que la mayoría de equipos deja por defecto sin entenderlos. Esta es la guía de decisión que usamos para configurarlo bien —y para saber cuándo Cloud Run no es la respuesta.

Por qué Go y Cloud Run encajan tan bien

Cloud Run cobra por lo que ejecutas y escala en función de la demanda, incluso hasta cero instancias. Ese modelo premia a los runtimes que arrancan rápido, consumen poca memoria y aguantan mucha concurrencia por proceso. Go cumple las tres:

  • Arranque en milisegundos. Un binario Go compilado no tiene JIT que calentar ni runtime pesado que inicializar. Eso reduce el cold start, que es precisamente el punto débil de cualquier plataforma serverless.
  • Contenedores pequeños. Una imagen scratch o distroless con un binario estático pesa pocos MB. Menos que descargar y arrancar, menos cold start.
  • Concurrencia real con goroutines. Cloud Run enruta varias peticiones a la misma instancia. Go maneja esa concurrencia con un coste de memoria por goroutine mínimo, así que una sola instancia rinde mucho antes de necesitar otra.

La consecuencia práctica: con Go pagas menos instancias para el mismo tráfico y sufres menos los arranques en frío. Cloud Run ya ofrece el runtime de Go 1.26 en disponibilidad general, así que no hay razón para quedarse atrás.

Cómo escala Cloud Run de verdad

Aquí es donde se pierde el dinero. Cloud Run no escala "por CPU" a secas; combina varias señales, y todas son configurables.

Concurrencia por instancia. Es el parámetro más importante y el peor entendido. El valor por defecto es 80 peticiones concurrentes por instancia. Si tu API en Go hace sobre todo trabajo I/O-bound (llamadas a base de datos, a otros servicios), probablemente aguante bastante más de 80 sin despeinarse, y subir la concurrencia significa menos instancias y menos factura. Si cada petición quema CPU (transcodificación, criptografía, parsing pesado), 80 es demasiado y querrás bajarla para no degradar la latencia.

Señales de autoescalado. Cloud Run añade instancias cuando la utilización supera un objetivo del 60 %, tanto en CPU como en concurrencia de peticiones, evaluado de forma continua en ventanas de 1 y 10 minutos. Cuando ninguna instancia disponible puede atender una petición, entra el escalado bajo demanda: la petición espera en cola un máximo de 10 segundos o 3,5 veces el cold start estimado antes de forzar el arranque de una instancia nueva.

Instancias mínimas y máximas. Por defecto el mínimo es 0 (escala a cero cuando no hay tráfico) y el máximo por defecto es 100 por revisión. Tras terminar de atender peticiones, Cloud Run puede mantener una instancia caliente hasta 15 minutos para amortiguar el siguiente pico.

ParámetroValor por defectoCuándo tocarlo
Concurrencia por instancia80Súbela en APIs I/O-bound; bájala en cargas CPU-bound
Instancias mínimas0Ponla a 1+ para eliminar el cold start en rutas críticas
Instancias máximas100 / revisiónSúbela para picos grandes; bájala como tope de presupuesto y para proteger la base de datos
Objetivo de utilización60 %Ajústalo con los controles de escalado (Preview) si tu perfil lo requiere

Ese tope de instancias máximas cumple una doble función que conviene interiorizar: es tu cortafuegos de presupuesto y, sobre todo, tu protección de la base de datos. Un pico de tráfico con max-instances sin límite puede abrir miles de conexiones a tu Postgres y tumbarlo; el error se convierte en peticiones encoladas en lugar de una caída en cascada.

Cold starts: el matiz que Go no resuelve solo

Es tentador pensar que, como Go arranca rápido, los cold starts desaparecen. No es cierto. El cold start es arranque del contenedor más tu inicialización: abrir el pool de conexiones a la base de datos, leer secretos, cargar configuración, calentar cachés. Go te da una ventaja enorme en la primera parte, pero si tu main() tarda 800 ms en establecer conexiones, ese es tu cold start real.

Dos reglas que aplicamos:

  1. Inicialización perezosa de lo caro. No abras conexiones a servicios que quizá no se usen en la primera petición. Difiere lo que puedas.
  2. min-instances = 1 solo en las rutas que lo justifiquen. Mantener una instancia caliente elimina el cold start, pero la pagas 24/7. Es una decisión de negocio, no técnica: reserva ese gasto para el endpoint cuyo p99 mueve una métrica de producto.

El coste real: los dos modelos de facturación

Este es el mayor generador de facturas sorpresa. Cloud Run tiene dos modelos y elegir mal cuesta dinero o rompe funcionalidad.

Facturación por petición (por defecto). Solo pagas cuando la instancia procesa peticiones, arranca o se apaga. Fuera de eso, la CPU está throttled: prácticamente congelada. Ideal para tráfico intermitente, bursty o con valles largos.

Facturación por instancia. Pagas todo el ciclo de vida de la instancia, haya o no peticiones, y a cambio la CPU está siempre disponible. Es lo que necesitas para trabajo en segundo plano: goroutines que procesan colas, agentes de OpenTelemetry, tareas programadas dentro del propio servicio.

Por petición (default)Por instancia
CobroSolo durante petición + arranque/apagadoTodo el ciclo de vida
CPU en idleThrottledSiempre disponible
Encaja conTráfico intermitente o con picosTráfico constante y trabajo en background
RiesgoPagas instancias ociosas

El error clásico en Go: lanzas una goroutine para procesar algo "después" de responder la petición, en un servicio con facturación por petición. Esa goroutine se congela en cuanto respondes, porque la CPU se retira. Si necesitas background, o pasas a facturación por instancia con un mínimo de instancias, o —mejor— sacas ese trabajo a Cloud Tasks / Pub/Sub / Cloud Run Jobs. El Recommender de Google puede analizar tu patrón mensual y sugerirte el cambio de modelo si te ahorra dinero, pero no sustituye entender por qué.

Cuándo NO usar Cloud Run

Cloud Run es un gran punto de partida, no un martillo universal. No lo elegiríamos en estos casos:

  • Conexiones persistentes de larga duración a gran escala. WebSockets o streaming server-to-server sostenido durante horas y con mucho volumen encajan mejor en un modelo con instancias fijas; en Cloud Run acabas peleando con timeouts y con el modelo de escalado.
  • Latencia p99 crítica con tráfico intermitente y cero tolerancia a cold starts. Puedes resolverlo con min-instances, pero si el número de instancias mínimas necesario es alto, el ahorro de serverless desaparece y GKE con autoescalado puede salir más barato y predecible.
  • Trabajos por lotes largos que superan el timeout de una request. Para eso está Cloud Run Jobs, no el servicio HTTP.
  • Necesitas control fino de red, sidecars, mallas de servicio o GPU sostenida. Ahí GKE (o GKE Autopilot) te da el control que Cloud Run deliberadamente esconde.
  • Ya tienes una plataforma Kubernetes madura y un equipo que la opera. Si el coste de plataforma ya está pagado, meter un servicio más en tu clúster puede ser más barato y coherente que abrir otra superficie operativa.
CriterioCloud RunGKE
Coste operativoMínimo (gestionado)Requiere equipo de plataforma
Escalado a ceroNativoComplejo
Control de red / sidecars / GPULimitadoTotal
Tráfico intermitenteIdealSobredimensionado
Escala alta y sostenidaPuede encarecerseSuele ser más eficiente

Nuestra recomendación

Para la inmensa mayoría de APIs y backends de producto, empieza en Cloud Run con Go 1.26, facturación por petición, min-instances a 0 y una concurrencia ajustada a tu perfil de carga (mide, no adivines). Sube instancias mínimas solo en los endpoints donde el cold start duela de verdad, y saca el trabajo en segundo plano fuera del servicio HTTP. Migra a GKE cuando —y solo cuando— la escala sostenida, el control de red o la economía te lo pidan con números encima de la mesa, no por defecto.

La regla de oro es la misma de siempre: mide antes de optimizar. Cloud Run te da los mandos; la factura y la latencia dependen de cómo los uses.

En Dribba llevamos años construyendo backends en Go sobre Cloud Run con un equipo 100 % senior in-house. Si estás decidiendo la arquitectura de tu próximo producto o afinando el coste de uno en producción, así es como trabajamos la ingeniería de alto rendimiento. Y si tu backend tiene que orquestar modelos o agentes, mira cómo abordamos la integración de IA en software.