|

El fallo serverless que nadie vio venir

Un equipo descubrió que su motor serverless para un juego de treasure hunt tenía latencias de hasta 10 segundos que afectaban al 1% de usuarios. La causa no era falta de recursos, sino routing inadecuado, queries excesivas a la base de datos, y una capa de configuración llamada Veltrix que nadie había tuneado para ese caso de uso específico.

En 30 segundos

  • Un equipo detectó latencias de 10 segundos en el 1% de sus usuarios — no por falta de poder de cómputo, sino por mala arquitectura.
  • Las tres causas raíz: routing deficiente, demasiadas queries a BD por request, y la capa Veltrix configurada con valores genéricos.
  • Escalar horizontalmente (tirar más lambdas al problema) retrasó el colapso pero no lo evitó.
  • La solución fue dividir Veltrix en dos componentes: uno para picos de tráfico y otro para períodos tranquilos.
  • Sin monitoreo granular (X-Ray, CloudWatch), el problema hubiera pasado desapercibido hasta que el 1% se volviera 20%.

El problema real detrás de la latencia serverless

Los problemas de arquitectura serverless rara vez se anuncian solos. Te enterás por un usuario que se queja, por una métrica que explotó, o si tenés suerte, por un alerta que configuraste antes. En este caso, las herramientas de monitoreo del equipo estaban “gritando”, según el postmortem publicado el 23 de mayo de 2026, pero nadie prestaba atención porque las instancias de lentitud eran “dispersas y aisladas”.

Hasta que un evento particular rompió ese patrón: 10 segundos de latencia en requests reales, afectando al 1% de la base de usuarios.

Para un juego — treasure hunt, con lógica de estado, ubicaciones, pistas y jugadores compitiendo en tiempo real — ese 1% no es ruido estadístico. Es la diferencia entre ganar o perder la pista siguiente mientras otro jugador ya la resolvió. La experiencia se rompe, el usuario se va, y no vuelve.

La arquitectura serverless es la que usa funciones stateless que se ejecutan bajo demanda (AWS Lambda es el ejemplo más conocido). El modelo promete escalar solo, cobrar por uso, y olvidarte de la infraestructura. Lo que no promete es que una configuración genérica va a funcionar para tu caso de uso específico.

Diagnóstico inicial: identificar las causas raíz

La investigación del equipo encontró tres problemas conviviendo:

  • Routing inadecuado: los requests no llegaban al handler más cercano ni al más disponible. Había colisiones que generaban colas invisibles.
  • Queries excesivas a base de datos: cada request disparaba múltiples consultas que podían haberse resuelto en una sola, o cacheado entre llamadas.
  • Veltrix mal configurado: esta capa de configuración estaba usando valores por defecto, no tuneados para el patrón de tráfico de un juego con picos cortos y períodos de silencio.

Eso sí: ninguno de los tres problemas era fatal por separado. El lío es que los tres convivían y se amplificaban. Un request con routing subóptimo llegaba a una función que hacía 8 queries donde podría hacer 2, todo orquestado por Veltrix con timeouts y pools configurados para una aplicación CRUD aburrida, no para un juego. Ya lo cubrimos antes en alternativas modernas de CI/CD.

¿Y qué pasó cuando lo miraron en producción con más detalle? Exacto: la latencia no era aleatoria. Aparecía en picos de uso, cuando el sistema más necesitaba rendimiento.

El primer enfoque fallido: tirar más plata al problema

El instinto inicial fue escalar. Más memoria para las Lambdas, más concurrencia reservada, más poder de cómputo. Funciona por un rato. Este es uno de los errores más documentados en arquitecturas serverless: confundir “tengo recursos” con “tengo una buena arquitectura”.

El equipo reconoce en su análisis que la estrategia “solo pospuso lo inevitable”. Los rendimientos decrecientes son reales: duplicar la memoria no duplica el throughput cuando el cuello de botella es la cantidad de queries a la BD, no la CPU de la función.

Ponele que tu función Lambda tarda 3 segundos por culpa de 15 queries encadenadas. Darle el doble de RAM no cambia nada — esas queries siguen siendo 15, siguen esperando respuesta de la BD, siguen bloqueando. La “solución” de escalar verticalmente solo hace que el problema llegue más tarde, con más usuarios adentro cuando explota.

La solución arquitectónica: dividir responsabilidades

Después de la refactorización del código, la decisión central fue partir la capa Veltrix en dos componentes con responsabilidades distintas:

  • Componente de picos de tráfico: configurado con pools de conexiones más grandes, timeouts más agresivos, y lógica de fallback para absorber ráfagas.
  • Componente de bajo tráfico: más conservador en recursos, optimizado para cold starts frecuentes, con pools más chicos que no consuman conexiones innecesariamente.

Esta separación ataca el problema real. Un juego de treasure hunt no tiene tráfico lineal — tiene momentos de silencio y momentos donde 200 usuarios abren la app al mismo tiempo porque alguien compartió un link. Configurar una sola capa para cubrir esos dos escenarios es pedirle a un solo traje que te quede bien tanto en el gym como en una reunión formal. Cubrimos ese tema en detalle en ejecutar procesos sin depender de cloud.

El resultado fue una mejora concreta en el comportamiento durante picos, aunque el postmortem no publica números de latencia post-fix (lo cual, seamos honestos, es una omisión llamativa en un análisis técnico).

Monitoreo y detección temprana de problemas

El detalle que salva esta historia es que el equipo tenía herramientas de monitoreo funcionando. Sin eso, el problema seguía hasta que el 1% de usuarios afectados se volvía 10%.

Para arquitecturas serverless en AWS, las herramientas mínimas son:

  • AWS X-Ray: trazabilidad distribuida por request. Te muestra exactamente dónde se fue el tiempo — si fue en la función, en la BD, o esperando que otra Lambda respondiera.
  • CloudWatch Logs Insights: queries sobre los logs para encontrar patrones. ¿Qué tienen en común los requests lentos? X-Ray te muestra el árbol, CloudWatch te deja hacer preguntas.
  • Métricas de duración en percentil 95 y 99: el promedio miente. Una Lambda que promedia 200ms con un P99 de 8 segundos es una catástrofe con buenas relaciones públicas.

Habilitar X-Ray en Lambda es cuestión de dos configuraciones: activar el tracing activo en la función y agregar el SDK de X-Ray como dependency. El costo adicional es marginal; la visibilidad que da es irreemplazable.

Comparativa: configuración genérica vs. configuración por caso de uso

AspectoConfig genéricaConfig por caso de uso
Pool de conexiones BDFijo, tamaño medioVariable según carga esperada
TimeoutsValor default del frameworkTuneado a P95 real del sistema
Cold startsNo consideradosProvisioned concurrency en funciones críticas
RoutingRound-robin básicoBasado en latencia y disponibilidad real
MonitoreoLogs básicosX-Ray + CloudWatch + alertas en P95
Resultado bajo picoLatencia impredecibleComportamiento controlado y medible
problemas de arquitectura serverless diagrama explicativo

Qué está confirmado y qué no

  • Confirmado: latencia de 10 segundos afectando el 1% de usuarios, tres causas raíz identificadas, refactorización de Veltrix en dos componentes.
  • Confirmado: el escalado horizontal no resolvió el problema de fondo.
  • No publicado: métricas de latencia post-fix. El análisis describe la solución pero no publica los números de mejora.
  • No especificado: el volumen total de usuarios del sistema, ni el costo de la infraestructura antes y después del cambio.

Lecciones clave para arquitecturas serverless

Si estás construyendo algo sobre Lambda u otro runtime serverless, este caso aporta un par de verdades incómodas.

Primero: las configuraciones default están pensadas para el caso promedio, no para tu caso. Si tu app tiene un patrón de uso particular (picos cortos, ráfagas por eventos, tráfico nocturno casi nulo), necesitás configuraciones distintas para distintos momentos del ciclo de vida.

Segundo, y más importante: el costo real de los problemas de arquitectura serverless no está en el precio de las funciones. Está en el tiempo de ingeniería para diagnosticar qué salió mal cuando los síntomas son dispersos, las métricas mienten por agregación, y el problema solo aparece bajo carga real. Los desafíos de serverless documentados por Prisma incluyen exactamente esto: la dificultad de reproducir en local lo que pasa en producción bajo tráfico real.

Tercero: los cold starts siguen siendo un problema no resuelto para aplicaciones interactivas. Si tu Lambda no recibió tráfico en los últimos minutos y llega un usuario, la primera invocación paga el costo de inicialización — que con runtimes pesados (Java, .NET) puede ser de varios segundos por sí solo. Para juegos, eso es inaceptable. Esto se conecta con lo que analizamos en seguridad en pipelines y deployments.

Si tu infraestructura corre en cloud y necesitás hosting confiable para la capa web de tu aplicación, donweb.com tiene opciones de cloud con soporte local.

Errores comunes en arquitecturas serverless

Error 1: medir el promedio en vez del percentil 95. El promedio de latencia te dice cómo le va al usuario típico. El P95 y P99 te dicen qué tan seguido un usuario tiene una experiencia pésima. En un juego, ese usuario con experiencia pésima escribe el review negativo en la app store.

Error 2: asumir que serverless elimina la gestión de conexiones a BD. No la elimina; la hace más complicada. Cada invocación de Lambda puede abrir una conexión nueva a tu base de datos relacional. Con alta concurrencia, agotás el pool de conexiones del servidor de BD antes de que las Lambdas tengan problema. Este es uno de los problemas de performance más frecuentes y la solución generalmente pasa por un proxy como RDS Proxy.

Error 3: no separar ambientes de carga. Desarrollar y testear en local con una sola invocación no reproduce la concurrencia real. El bug de Veltrix que describe este caso probablemente era visible bajo carga pero invisible en tests unitarios. Si no tenés un ambiente de staging con traffic simulation, estás probando en producción sin saberlo.

Preguntas Frecuentes

¿Por qué mi aplicación serverless tiene latencia alta aunque tenga memoria suficiente?

La memoria de la función no es el único factor. La latencia alta en Lambda suele venir de cold starts (la función no estaba “caliente”), de queries ineficientes a bases de datos, de configuraciones de timeout mal calibradas, o de chains de funciones que esperan respuesta entre sí. Revisá primero con X-Ray dónde se va el tiempo antes de tocar la memoria.

¿Cómo diagnostico problemas de performance en Lambda?

Habilitá AWS X-Ray con active tracing en la función. Esto genera un mapa de cada request con el tiempo gastado en cada segmento — tu código, llamadas a BD, llamadas a otros servicios. Combinalo con CloudWatch Logs Insights para hacer queries sobre tus logs y encontrar el patrón detrás de los requests lentos. Mirá métricas en P95 y P99, no en promedio.

¿Cuál es la mejor forma de escalar aplicaciones serverless con picos de tráfico?

Antes de escalar, arreglá la arquitectura. Si el problema es de queries excesivas o configuración genérica, más recursos solo retrasan el colapso. Una vez que la arquitectura es correcta, usá provisioned concurrency para funciones críticas (evita cold starts), configurá pools de conexiones a BD con un proxy (RDS Proxy para bases relacionales), y separé la configuración para picos de la configuración para tráfico normal. Relacionado: plataformas de deployment a considerar.

¿Qué son los cold starts y cuánto afectan la latencia?

Un cold start ocurre cuando Lambda necesita inicializar una nueva instancia de tu función porque no hay ninguna “caliente” disponible. El tiempo adicional varía según el runtime: Node.js y Python arrancan en milisegundos; Java y .NET pueden tardar entre 1 y 5 segundos. Para aplicaciones interactivas o juegos, esto es inaceptable. La solución es provisioned concurrency: pagás para mantener N instancias siempre inicializadas.

¿Cuándo tiene sentido usar arquitectura serverless y cuándo no?

Serverless es bueno para workloads con tráfico impredecible, tareas asíncronas en background, o APIs con picos cortos y períodos de silencio. No es la mejor opción para aplicaciones con latencia ultra-baja como trading o juegos competitivos en tiempo real, ni para workloads con conexiones persistentes a BD de alta frecuencia. El caso del treasure hunt está en el límite: es viable, pero requiere tuning cuidadoso.

Conclusión

Lo que describe este postmortem no es un caso raro. Es el patrón habitual de un equipo que adopta serverless atraído por la promesa de “escala solo” y descubre que “escala solo” no significa “funciona bien solo”. La diferencia está en la configuración específica para el caso de uso real.

La lección más valiosa no es técnica. Es de proceso: tuvieron monitoreo, encontraron el problema antes de que fuera catastrófico, y en vez de parchar con más recursos, investigaron la raíz. Eso es lo que separa un equipo que mantiene sistemas saludables de uno que vive apagando incendios.

Si estás construyendo sobre Lambda hoy, revisá si tu capa de configuración está tuneada para tu caso de uso o si es la configuración default que venía en el tutorial de onboarding.

Fuentes

Te puede interesar...