commit&push

~/blog $ git show 2026-08-22

Lo que hace falta para operar la puerta de un evento real

· 7 min de lectura · Victor Benavides

--ops--incidents

Feria Arequipa duró nueve días este mes, y mi plataforma operó la puerta.

No un demo. No un piloto con un cliente amable que perdonaría una mala tarde. Asistentes reales, staff real, torniquetes reales en una feria real — donde "el sistema está caído" no significa un dashboard en rojo, significa una fila de seres humanos que no avanza.

Ellos dijeron que sí a eso. Este es el recuento honesto de lo que pasó, incluidas las partes que preferiría omitir.

Día uno, en números

El primer día completo se vio así:

  • 1,846 lecturas de credencial en las puertas
  • 1,001 credenciales distintas — cerca de mil personas diferentes
  • 4 lectores en operación
  • 0.7 segundos de tiempo mediano de lectura
  • hora pico a las 11:00, con 239 lecturas en sesenta minutos

Ese 0.7s es el número que me importa. El control de acceso tiene un requisito brutal e innegociable que la mayoría del software no tiene: hay una persona parada frente al lector. Cada segundo extra es un segundo de alguien esperando, multiplicado por todos los que vienen detrás. Un request web que tarda tres segundos es molesto. Un escaneo de credencial que tarda tres segundos, a 239 lecturas por hora, es una fila.

Y entonces llegó el viernes

A las 17:33 de un viernes por la noche, durante el evento, los logins dejaron de funcionar.

La autopsia técnica ya la escribí — un mantenimiento forzado de infraestructura rotó los nodos del clúster, el componente que adjunta sidecars a los pods nuevos también estaba rotando, y su configuración decía "si no estoy disponible, deja que los pods arranquen igual". Catorce servicios levantaron sin poder hablar con nada, reportando salud perfecta.

Aquí está la parte que me importa para este post: las puertas siguieron escaneando.

Solo se rompieron los logins nuevos. Los lectores y el staff ya tenían tokens válidos, y el camino del escaneo no depende del camino del login — así que lo que tenía una fila enfrente siguió funcionando mientras lo de atrás se incendiaba. La recuperación tomó minutos una vez que entendimos: borrar los pods nacidos a medias y dejar que se recrearan bien.

Ahora la mitad honesta. Eso fue diseño y suerte, y no voy a fingir que fue todo diseño.

La parte de diseño es real: que la autenticación no esté en el camino crítico de cada escaneo es una decisión deliberada, y esa noche se ganó su lugar. La parte de suerte es igual de real: era el día de apertura, el tráfico era ligero, y los tokens en circulación no habían expirado. Mueve esa misma falla al sábado a las 11:00 — 239 lecturas por hora, staff necesitando re-autenticarse — y estaría escribiendo un post muy distinto.

Ese escenario contrafactual es por qué el arreglo permanente importa. La configuración ahora dice lo contrario: si el sidecar no se puede adjuntar, que el pod no arranque. Negarse ruidosamente en vez de continuar en silencio. Es mejor tener un pod que no arranca que un pod que miente sobre estar listo.

El problema que nadie notó

Revisando los datos después, encontré algo que nadie reportó y ninguna alerta detectó.

Desde las 19:00 en adelante, el tiempo mediano de lectura pasó de 0.7 segundos a 2.1 segundos — y se quedó ahí hasta el cierre. Tres veces más lento.

La parte rara: esto pasó mientras el tráfico bajaba. La hora más ocupada del día fue de las más rápidas. Las horas más lentas fueron las más vacías. Eso es al revés de cómo esperas que se comporte un sistema, y es la firma de cosas enfriándose — conexiones, cachés, recursos agrupados expirando en silencio entre requests, de modo que cada escaneo nuevo paga un setup que el anterior ya había pagado.

Nadie se quejó, porque a 50 lecturas por hora nadie siente 2.1 segundos. Pero mete esa misma degradación en la hora pico de las 11:00 y es una fila visible en la puerta principal. Encontré un problema que todavía no le había dolido a nadie — que es el único momento cómodo para encontrar uno.

La lección que no es de software

El lector de la puerta principal se puso lento después de trece horas de batería.

Eso es todo. Esa es la falla completa. Un dispositivo que llevaba despierto desde la mañana empezó a limitarse solo, y toda la ingeniería de backend del mundo no tenía nada que decir al respecto. Es el tipo de cosa que no puedes testear, ni simular, ni predecir desde una laptop — porque tu laptop está enchufada y lleva cuarenta minutos encendida.

Las convenciones necesitan planificación de energía: baterías en cada puerta, una rotación de carga, y el modo de ahorro explícitamente desactivado en los dispositivos lectores. Los locales de nightlife no tienen este problema — un bar opera cuatro horas, no trece. Solo sé la diferencia porque estuve parado en uno y lo vi pasar.

Y los humanos hicieron lo que hacen los humanos

Cerca del 15% de todas las lecturas fueron rechazos, y casi todos decían lo mismo: ya se encontraba dentro.

No atacantes. No bugs. Gente saliendo por una puerta lateral a almorzar sin marcar salida, y volviendo a entrar para que el sistema les dijera, correctamente, que ya los tenía adentro.

La máquina de estados tenía razón. Los usuarios no la habían leído. Ese hueco no es un defecto que arreglas en código — es señalización, staff recordando en las salidas, y diseñar asumiendo que la gente en una feria está pensando en el almuerzo y no en tu modelo de presencia.

Qué cambiaría

  • Fallar ruidosamente, no en silencio. Hecho — la configuración del sidecar está invertida, de forma permanente.
  • Hacerle a los health checks la pregunta que importa. No "¿está arriba el proceso?" sino "¿puede alcanzar lo que necesita?". Un pod reportando Running mientras está sordo es peor que uno claramente caído.
  • Mirar la latencia contra la carga, no solo contra un umbral. Ponerse más lento mientras hay menos tráfico es una señal, y ninguna alerta que tenía estaba diseñada para atraparla.
  • Llevar energía. Poco glamoroso, decisivo, y el único arreglo de esta lista que no cuesta nada implementar.
  • Pedir que marquen la salida. La mayoría de ese 15% se resuelve con un letrero y una persona diciendo "marca antes de salir".

El resumen honesto

Cuatro cosas salieron mal en nueve días: una caída durante el evento, una degradación al triple que nadie notó, un lector limitado por su propia batería, y una tasa de rechazos causada enteramente por comportamiento humano.

Y las puertas siguieron avanzando. Mil personas entraron el día uno, con escaneos por debajo del segundo, y las fallas o se quedaron detrás de escena o fueron absorbidas por decisiones tomadas meses antes.

Pude haber escrito este post como una vuelta de la victoria. Pero "no salió nada mal" es una afirmación que nadie con experiencia se cree, y no es lo que pasó. Lo que pasó es que las cosas salieron mal y el evento no las sintió — que es algo más pequeño, más cierto, y mucho más difícil de construir.

Gracias a Feria Arequipa por la confianza. El martes: lo que los tests no te pueden mostrar — que, como habrás adivinado, son casi todos los grandes éxitos de este post. ✨

$ grep -rl --tag ~/blog