Revisión de incidente: carga de base de datos, fallos en cascada y lo que aprendimos - 27 de enero de 2026
El martes 27 de enero sufrimos un incidente en producción que provocó un rendimiento degradado en toda la plataforma y una caída total para algunos clientes enterprise con enlaces de programación de gran volumen. El incidente empezó como una carga elevada de la base de datos, pareció resuelto y luego reveló fallos secundarios en sistemas dependientes. Esta entrada explica qué pasó, cómo lo confirmamos y qué cambiamos como resultado.

Impacto
-
Los usuarios de bajo volumen experimentaron alta latencia y cargas de página lentas
-
Los clientes enterprise con enlaces de programación intensivos experimentaron timeouts y caída del servicio
-
Más tarde, durante el incidente, los usuarios con integraciones de Google Calendar vieron fallos intermitentes
Lo primero que vimos
A las 15:30 UTC se activaron alertas automáticas por una carga elevada de la base de datos. La investigación inicial mostró un aumento de Average Active Sessions (AAS) y una latencia de las sentencias en rápido ascenso, mientras que el tráfico general se mantenía dentro de los márgenes esperados.

Lo que muestra este gráfico:
-
Un aumento sostenido de sesiones activas de la base de datos
-
Las sesiones se acumulaban en vez de completarse rápidamente
-
Una señal clara de que las consultas se estaban volviendo más lentas, no de que hubiera aumentado el tráfico
Esto sugería un cambio en nuestra aplicación y no un pico de tráfico, algo que el análisis de tráfico confirmó.
La saturación de CPU confirma el cuello de botella
A medida que aumentaba la carga, el uso de CPU de la base de datos también subió.


Lo que muestran estos gráficos:
-
La utilización de CPU subiendo claramente por encima de la línea base
-
Saturación sostenida en lugar de picos breves
-
Una correlación clara con el aumento de la latencia de las consultas
En este punto, Postgres estaba limitado por la CPU. Las consultas tardaban más, bloqueaban a otras y la latencia se extendía por todo el sistema.
Cronología (UTC)
-
15:30 – Alertas automáticas por alta carga en la BD. El diagnóstico inicial mostró actividad elevada de
DELETEen APIv2. -
15:49 – Apretamos los límites de velocidad de
DELETEpara reducir la presión inmediata. -
16:03 – Una investigación más a fondo mostró que el tráfico era normal. La carga de la base de datos seguía aumentando.
-
16:06 – Primeros reportes de clientes enterprise que no podían cargar enlaces de programación.
-
16:18 – Se declara el incidente. La saturación de CPU hizo que aumentara la latencia de las sentencias en todo el sistema.
-
17:07 – Empezamos a reescribir una consulta de alta carga para reducir la presión sobre la base de datos.
-
17:40 – Se desplegó la reescritura de la consulta. Ayudó, pero no resolvió el problema del todo.
El punto de inflexión clave
A las 17:45 identificamos una interacción no prevista:
Una función reciente lanzada el lunes 26 introdujo la búsqueda de reservas dentro de KBar (CMD+K). Esto hizo que una llamada pesada a la API se ejecutara en cada carga de página en la app web.
A las 17:55, el cambio de KBar se revirtió en producción.

Lo que confirma este gráfico:
-
Una caída clara e inmediata del AAS tras la reversión
-
Reducción de la presión de consultas en la base de datos
-
La latencia se estabilizó poco después
Esto encaja exactamente con el momento de la reversión y confirmó la interacción con KBar como el desencadenante principal del incidente de la base de datos.
- 18:15 – El rendimiento de la base de datos se estabilizó.
En ese momento se resolvió el incidente principal de la BD.
Problemas secundarios detectados
Tras recuperarse la base de datos, un subconjunto más pequeño de usuarios siguió afectado.
Los usuarios con integraciones de Google Calendar experimentaron fallos debido al agotamiento de la cuota de Google API. Esto se debió al comportamiento de reintento en varios consumidores mientras se producían errores aguas arriba.

Lo que muestra este gráfico:
-
Consumo rápido de cuota durante la ventana del incidente
-
Correlación con el comportamiento de reintento en lugar de con tráfico nuevo
-
18:40 – Causa raíz identificada: la lógica de reintento de Atoms refrescaba los calendarios de forma agresiva.
-
18:46 – La funcionalidad de Atoms se interrumpió temporalmente. Los eventos del calendario se completaron retrospectivamente y el uso de cuota bajó.
-
18:54 – El rendimiento de APIv2 siguió ligeramente degradado; parte del tráfico se redirigió temporalmente a endpoints de Vercel.
-
19:30 – APIv2 y las integraciones de Google se estabilizaron por completo.
Más tarde, identificamos otro problema contribuyente:
- Una llamada promisificada no esperada hizo que los procesos de Node se bloquearan cuando los errores de Google API se filtraban al ámbito global.
Causa raíz
La causa principal fue una interacción inesperada entre funciones:
-
KBar activó una llamada pesada a la API en cada carga de página
-
Esa ruta de API dependía de consultas costosas a la base de datos; en especial para usuarios a gran escala con muchas reservas.
-
La saturación de CPU aumentó la latencia de las consultas en todo el sistema
-
Los clientes enterprise con enlaces de programación de gran volumen fueron los más afectados
Los fallos secundarios (agotamiento de cuota de Google e inestabilidad de APIv2) no fueron la causa original, pero quedaron al descubierto cuando el sistema estuvo bajo presión.
Qué cambiamos
Desde el martes, hemos:
-
Eliminado la dependencia de KBar que activaba llamadas pesadas a la API (#27314)
-
Lanzado varias optimizaciones de consultas para reducir la carga de la BD (#27364, #27319, #27309, #27315)
-
Cambiado la paginación de
/booking/{upcoming,…}de pre-renderizada a bajo demanda, reduciendo el uso de la base de datos mientras seguimos optimizando el endpoint (#27351) -
Corregido la llamada async no esperada que provocaba bloqueos del proceso de Node en APIv2(#27313)
-
Implementado varias medidas de protección a nivel de BD para proteger nuestra base de datos durante periodos de uso extremo.
-
Limitado las llamadas a endpoints DELETE a 1 petición por segundo (#27359)
Cierre
Este incidente no lo provocaron picos de tráfico ni un fallo de infraestructura. Lo provocó una interacción inesperada entre funciones, con problemas en cascada debidos al comportamiento de reintento de sistemas dependientes y a un error sutil de la aplicación.
Lamentamos la interrupción, especialmente para los clientes que operan a gran escala. El incidente del martes nos sirvió de base para mejorar cómo lanzamos funciones, protegemos nuestra base de datos y gestionamos los fallos en cascada.
Gracias por tu paciencia y por exigirnos un nivel alto.
